Skip to content
The core implementation of the asset pipeline for the jvm
JavaScript HTML Groovy CSS Java Ruby Other
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
asset-pipeline-classpath-test fixed a lot of features in gradle integration, added new config optio… Apr 22, 2016
asset-pipeline-core Improved hashing of assets (#248) Nov 21, 2019
asset-pipeline-docs fixing updates Jul 3, 2019
asset-pipeline-gradle improving asset-pipeline codebase to handle grails4 and spring boot 2 Mar 19, 2019
asset-pipeline-grails file uri fix was placed in wrong order Aug 22, 2018
asset-pipeline-micronaut cleaning up tests Feb 28, 2019
asset-pipeline-servlet fixing jetty classloader vulnerability with potential reverse file tr… Aug 22, 2018
asset-pipeline-site fixing updates Jul 3, 2019
asset-pipeline-spring-boot removing a println Jul 26, 2018
coffee-asset-pipeline optimizations for handlebars and coffee compilers Mar 8, 2018
compass-asset-pipeline cleaning up tests Feb 28, 2019
ember-asset-pipeline Update handlebars runtime file to handlebars-runtime in docs (#208) Jun 6, 2018
gradle/wrapper initial micronaut assetpipeline module work May 23, 2018
groocss-asset-pipeline Update version of groocss to 1.0-M1 (#238) Mar 11, 2019
handlebars-asset-pipeline Update handlebars runtime file to handlebars-runtime in docs (#208) Jun 6, 2018
jsx-asset-pipeline fixing a bug with contextPath in grails and root level mappings Jul 19, 2018
less-asset-pipeline Change logging calls to use slf4j. Cleanup unused imports. (#250) Oct 28, 2019
ratpack-asset-pipeline Closes #242; Update to ratpack 1.6.1 and migrate to ratpack.service.* ( Jul 3, 2019
sass-asset-pipeline Support importing .sass files (#245) Nov 21, 2019
typescript-asset-pipeline wooh\! typescript support\! Jul 26, 2018
.gitignore deploying to morpheus web Apr 27, 2016
.travis.yml fixing version and travis test Jul 3, 2019
Readme.markdown Improved hashing of assets (#248) Nov 21, 2019
asset-pipeline-core.ipr adding plugin search and api docs in ascii doc May 23, 2016
asset-pipeline.iws more speed in response rendering, fixes to date modified now in respo… Mar 4, 2016
build.gradle fixing version and travis test Jul 3, 2019
gradlew stupid save failed Jan 16, 2017
gradlew.bat stupid save failed Jan 16, 2017
settings.gradle wooh\! typescript support\! Jul 26, 2018


Asset Pipeline Core

Build Status


The Asset-Pipeline is a plugin used for managing and processing static assets in JVM applications primarily via Gradle (however not mandatory). Asset-Pipeline functions include processing and minification of both CSS and JavaScript files. It is also capable of being extended to compile custom static assets, such as CoffeeScript or LESS.


  • Asset Bundling
  • Extensible Modules (Supports LESS,Handlebars,Coffeescript, Ember-Handlebars, SASS) via other modules.
  • Cache Digest Names (Creates cache digested names and stores aliases in a
  • Js Minification
  • Js SourceMap Generation
  • Css Minification / Relative Path assertion
  • File Encoding Support
  • GZIP File Generation
  • Last-Modified Header


Gradle Usage

If using gradle, this plugin adds a series of tasks directly to your gradle plugin. All you have to do is apply plugin:'asset-pipeline' after confirming this is in the classpath of your buildscript block. i.e.:

//Example build.gradle file
buildscript {
  repositories {
    maven {
      url ""
  dependencies {
    classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.10.1"

apply plugin: 'com.bertramlabs.asset-pipeline'

assets {
  minifyJs = true
  minifyCss = true
  enableSourceMaps = true
  configOptions = [:]
  minifyOptions = [
    languageMode: 'ES5',
    targetLanguage: 'ES5', //Can go from ES6 to ES5 for those bleeding edgers
    optimizationLevel: 'SIMPLE',
    angularPass: true // Can use @ngInject annotation for Angular Apps
  includes = []
  excludes = ['**/*.less'] //Example Exclude GLOB pattern

  //for plugin packaging
  packagePlugin=false //set to true if this is a library

  //developmentRuntime can be turned off

  //if you want to customize the jar task this task runs on you can specify a jarTaskName

  // Can add custom asset locations (directories or individual jar files)
  from '/vendor/lib'
  from '/path/to/file.jar'
  // can be used to customize the hashing of the assets
  digestAlgorithm = 'MD5'
  digestSalt = ''

dependencies {
  // Example additional LESS support
  // assets 'com.bertramlabs.plugins:less-asset-pipeline:{}'

Now that you have your build.gradle files. All you need to do is put files in your projects src/assets/javascripts, src/assets/stylesheets, src/assets/images, or whatever subdirectory you want. When you run gradle assetCompile these files will be processed and output into your build/assets folder by default.

Thats about all there is to it. Now you can use gradle to handle processing of all your client side assets.

Advanced Usage

The core part of asset-pipeline is rather agnostic to whichever implementation you want to use, be it servlet based, netty based, or whatever else you want to do. The recommended use case for this aspect of the plugin is to integrate with other plugins that are capable of being scoped to specific frameworks. Currently the best example of the use case for the asset-pipeline plugin is in the Grails framework.

The core plugin provides interfaces for asset resolution, processing, and compiling into a target directory. You can register resolvers in the AssetPipelineConfigHolder to essentially add scan paths for your static assets. This includes both File System support as well as Jar file support (ClassPathResolver coming soonish)

import asset.pipeline.*
import asset.pipeline.fs.*

def fsResolver = new FileSystemAssetResolver('application','assets')
def jarResolver = new JarAssetResolver('application','/path/to/file.jar','META-INF/assets')

As can be seen above, we have registered 2 examples of implementations of the AssetResolver interface

Now we can take advantage of asset-pipeline endpoints to fetch files for development mode as well as compiling files for production.

To Fetch a File in Development mode simply use the following endpoint:

class AssetPipeline {
	static byte[] serveAsset(uri, contentType = null, extension = null, encoding = null) {

	//Returns a dependency list of your asset (based on require directives)
	static def getDependencyList(uri, contentType = null, extension = null)

	//For skipping directive processing (when requiring files individually)
	static byte[] serveUncompiledAsset(uri, contentType, extension = null,encoding=null)

These endpoints are great when actively developing your application. They allow you to grab a file and process it on the fly without waiting for a watcher to reload.


In a compiled production environment, it is not recommended that files get resolved on the fly and processed like this. It adds a large amount of overhead to your application. To solve this, the Asset Pipeline provides an AssetCompiler. This is a configurable compiler that can scan your assets, process them, fingerprint them, and throw them into a target. The target can vary depending on the implementation of the framework in question. For example, in Grails we compile assets into the target/assets folder then copy those into the War file during war build. We then register a Servlet Filter that looks in this folder based on a url mapping to serve assets, check for gzip, set cache headers, and more.

def compiler = new AssetCompiler()


This extraction is not yet 100% complete and is in active development. If you are interested in implementing the asset-pipeline for a jvm framework. Feel free to take a look to get an idea what you will need to do.

CDN Notes (Last-Modified Header)

Some CDN providers rely on the existence of a Last-Modified header to successfully use the If-None-Match request header. This will be served up in production mode for assets served locally from asset-pipeline.


To accomodate varying uses of the groovy module (i.e. groovy-all vs. groovy) This library depends on groovy even though it does not directly export it. Make sure you add the following dependenices

dependencies {
  compile 'org.codehaus.groovy:groovy:2.0.7'
  compile 'org.codehaus.groovy:groovy-templates:2.0.7'
  //compile 'org.codehaus.groovy:groovy-all:2.0.7'


For Grails 3 asset-pipeline has to be provided both for Grails and Gradle. An example configuration could be:

// Add the Gradle plugin to the build dependencies and apply it to the build process
buildscript {
    dependencies {        
        classpath 'com.bertramlabs.plugins:asset-pipeline-gradle:2.10.1'
apply plugin: 'asset-pipeline'

// The plugin could also be applied with the newer syntax 
// plugins {
//     id "com.bertramlabs.asset-pipeline" version "2.10.1"
// }

dependencies {        
    // Add the Grails Plugin to the runtime dependencies
    runtime 'com.bertramlabs.plugins:asset-pipeline-grails:2.10.1'
    // Define needed asset-pipeline plugins with the special assets-scope 
    assets 'com.bertramlabs.plugins:less-asset-pipeline:2.10.1'
    assets 'com.bertramlabs.plugins:sass-asset-pipeline:2.10.1'


All contributions are of course welcome as this is an ACTIVE project. Any help with regards to reviewing platform compatibility, adding more tests, and general cleanup is most welcome. Thanks to several people for suggestions throughout development. Notably: Brian Wheeler (@bdwheeler), Rick Jensen (@cdeszaq), Bobby Warner (@bobbywarner), Ted Naleid (@tednaleid), Craig Burke (@craigburke1) and more to follow I'm sure...

When creating custom binary plugins to extend this (details also in the grails documentation) You will want to use groovy but not directly export it from gradle. Here is an example of how to do that.

configurations {
sourceSets {
    main {
        compileClasspath += configurations.provided

dependencies {
  provided 'org.codehaus.groovy:groovy-all:2.0.7'
  compile "com.bertramlabs.plugins:asset-pipeline-core:2.10.1"

Additional Resources

You can’t perform that action at this time.