Introducing WebJars – Web Libraries as Managed Dependencies

Update: I’ve created a Spring MVC WebJars example.
Update 2: Ukrainian translation here - http://softdroid.net/vvedennya-webjars by Eclipse Android.
Update 3: WebJars.org 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 "http://webjars.github.com/m2"
    )

}

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

<link rel='stylesheet' media='screen' href='@routes.Assets.at("stylesheets/bootstrap.min.css")' />

The “@routes.Assets.at” 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:

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:

<repositories>
        <repository>
            <id>webjars</id>
            <url>http://webjars.github.com/m2</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>com.github.twitter</groupId>
            <artifactId>bootstrap</artifactId>
            <version>2.0.2</version>
        </dependency>
    </dependencies>

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' />

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!