Introducing WebJars – Web Libraries as Managed Dependencies

Update: I’ve created a Spring MVC WebJars example.
Update 2: Ukrainian translation here – by Eclipse Android.
Update 3: has been officially launched! Learn more.

Our web apps are using more and more web libraries like jQuery, Backbone.js and Twitter Bootstrap. The traditional way to use those libraries is to locate & download the JavaScript and CSS source then just copy it into a project. To me this resembles how we used to just copy JAR files into a project’s WEB-INF/lib dir. But why not do with web libraries like we now do with Java libraries and specify them as managed dependencies? This allows us to declaratively set the version, use a consistent version across an application, and easily deal with transitive dependencies. Then we just need web frameworks that can serve static assets from JAR files and we are good to go! Luckily Play 2 and Dropwizard both have out-of-the-box support for this. So I decided to give it a try…

I packaged up some JavaScript and CSS web libraries into JARs, put them into a Maven repo and it worked! And thus the WebJars project was born!

Lets look at an example for how to use the Twitter Bootstrap WebJar in a Play 2 app. First we need to add the WebJars Maven repo to the Play 2 dependency resolvers and specify Bootstrap as a dependency. For Play 2 this is done in the “project/Build.scala” file. Here is one for my Play 2 WebJars Demo project:

import sbt._
import Keys._
import PlayProject._
object ApplicationBuild extends Build {
    val appName         = "play2_webjars_demo"
    val appVersion      = "1.0-SNAPSHOT"
    val appDependencies = Seq(
      "com.github.twitter" % "bootstrap" % "2.0.2"
    val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
      resolvers += "webjars" at ""

Now to use Bootstrap in a Scala template, we can just do:

<link rel='stylesheet' media='screen' href='"stylesheets/bootstrap.min.css")'>

The “” thing just gets a reverse route for the URL that will serve the “bootstrap.min.css” file from the Bootstrap WebJar. Note: It’s not necessary in Play 2 to use the reverse routing but it is a type safe way to get a URL. Based on the default routes in Play 2 the route to that file will be “/assets/javascripts/bootstrap.min.js” which we could have used instead.

Now here is the super cool part… The Bootstrap WebJar depends on jQuery so now I can also just use jQuery:

<script type='text/javascript' src='"javascripts/jquery.min.js")'></script>

That is super simple and now I’m managing my web libraries as dependencies!

Note: Play 2 actually puts a copy of jQuery in the default project template but hopefully for Play 2.1 they will pull it out and instead use the jQuery WebJar. In my demo project I’ve removed that copy of jQuery because it’s no longer needed.

If you want to use WebJars with Dropwizard then first setup the Maven “pom.xml” file with the WebJars repo and add the dependency:


Then add an “AssetBundle” that will serve static assets in the “public” directory on the “/public” URL path:

    addBundle(new AssetsBundle("/public/", 0, "/public"));

Now you can load the static assets in a web page:

    <link rel='stylesheet' media='screen' href='/public/stylesheets/bootstrap.min.css'>
    <script type='text/javascript' src='/public/javascripts/jquery.min.js'></script>

Get the full source code for the Dropwizard WebJars demo on GitHub.

I’m sure there are other Java web frameworks that support WebJars, so if you know of one, let me know and I’ll try to create more demo projects.

Right now there are just a couple WebJars in the repository but if you’d like to see others then create a new issue on GitHub and I’ll build a new WebJar.

Let me know what you think about WebJars. Thanks!

  • Scott Frederick

    This looks interesting James.

    Grails is another JVM-based web framework that supports something like this. Grails has a Resources plugin ( that helps manage static web resources. Other plugins build on Resources to manage dependencies on jquery, jquery-ui, bootstrap, and other libraries.

    It seems like a Resources plugin to WebJars bridge would make some sense, and should be easy to implement.

    • Yes it is!  Do you know if it can serve static assets from a JAR on the classpath?

      • Scott Frederick

         Sorry, I pressed the submit button too soon on my comment.

        The Resources-based plugins package static assets in a Grails plugin format. The resources get unpacked into the project structure when the plugin is installed. Again, it seems like using the Resources plugin as a way to support WebJars in Grails should be do-able.

        • Awesome.  I’ll have to give it a try.  Thanks!

  • Well guys, Apache Wicket is supporting this feature since first release in 2005 .. 

    • Awesome!  Can you point me to an example so that I can create a little demo app?

      • Hi James, 

        You may want to give a look here


        • Do you know which one of those has an example of serving static assets from a JAR?

          • Check it this

            And look for the PackageResourceRerefence in the Wicket javadocs

          • On that link I get:
            java.lang.OutOfMemoryError: PermGen space


    • Yeah, and Lift borrowed it from Wicket in late 06 / early 07, and all the external plugins for Lift (widgets etc) all use this technique. 

      • That is great to hear!  Is there already a repo that Lift users use to get common web libraries from?

        • Lift ships with a range of JS+CSS deps; they’re just sat in the core lib at the moment, but many people write external ones that plug into the asset resolution system. If you’re interested, take a look at ResourceServer in the code base, or Lift in Action, page 164 if applicable. Cheers :-)

          • Awesome!  Thanks Timothy.  I’ll have to create a simple Lift demo that uses WebJars.

  • Nraychaudhuri

    Interesting. I like the idea

  • Will this solution resolve the correct version of, say, jQuery when declared as a dependency?  Imagine I had Twitter Bootstrap and some arcane old jQuery plugin.  Now these 2 things have dependencies on two different versions of jQuery (the old plugin is locked to a very specific version) – will these things naturally co-exist or would there be some work involved in making this happen?

    • Yup!  That is exactly how the Java dependency managers work.  Right now I’ve made Twitter Bootstrap 2.0.2 depend on jQuery 1.7.1.  But if you want to use jQuery 1.5.1 (right now the only other version in the repo), then you can explicitly set it as a dependency and it will override the transitive dependency.

      • What happens then if I reference,“javascripts/jquery.min.js”)

        in my view?  What one does it pull in?  How do you pull both in if they are named the same in the jar?

        • That would reference which ever version the dependency manager has resolved.  The current implementation doesn’t allow you to use multiple versions of a web library in a single project.

          • Ah right gotcha.  I’d imagine this is a bit of an edge case anyhow but just wanted to be sure.

          • I thought about organizing things different so that you could do this.  I could make the artifactId for jQuery contain the major.minor version, like “jquery-1.7”.  I’d love to hear feedback on whether or not people think that approach would work better for them.

          • OK so I’ve seen about 2 projects in my entire career that mixed different versions of libraries and both were “legacy” projects undergoing migration.  In these cases you’d never have both under dependency management anyway.

            Soooooo with that in mind is the effort of changing strategy actually worth it?  I’d say yes but then I don’t know how much effort is involved!

  • Frank Wienberg

    James, thanks a lot for your great initiative! As you know, we at Jangaroo have been using Maven for (generated) JavaScript for quite a while. Independent of your project (which I stumbled upon only yesterday), we just started utilizing a Java feature new in Servlet 3, which standardizes how to package Web resources inside JARs. Inspired by your post / project, I just blogged about our approach, and would be happy if we could consolidate both projects! 

    • Hey Frank!  That is fantastic stuff!  I wasn’t aware of that feature of Servlet 3.  Very cool!

      I’d love to work with you guys on this.  I think there are two places we could work together right away:
      1) Would love to get you involved in defining the organization of WebJars:
      2) I’d love to get these into Maven Central like you’ve done.  Maybe you could help with that part?

      I love how we always think alike!  :)


      • Frank Wienberg

        It’s always a pleasure :-)
        I just commented on both issues!

  • Pingback: Edge Caching With Play 2, Heroku, and CloudFront()

  • Pingback: WebJars Officially Launched!()

  • Himanshu


    Questions regarding maven plugin:

    1) when we use the plugin with maven and do mvn webjars:install foo, will the dependency foo be downloaded right away and stored in some directory (like how bower downloads and stores in bower_components) ?

    2) If no then all that maven command does is modify the pom.xml and add the foo dependency. But during which maven phase (compile or package or install) are the webjar dependencies downloaded by the plugin ?

    3) If I want to create a webjar of my own maven based project how do I do it ? Is it necessary that the jar should have following structure like ?


    OR can I create my own directory structure ?