Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


A Leiningen plugin to generate fingerprinted files suitable for use in browser cache-busting.

It was designed with the specific usecase of fingerprinting CLJS files that are bundled as part of an uberjar alongside other clojure code in mind. lein-buster provides either auto-run hooks that invoke it after leiningen.compile or a task to invoke it manually from a project.

Once run, lein-buster will output two types of artifacts:

  1. A fingerprinted version of your specified files in the format of <filename>-<fingerprint>.<extension>.
  2. A manifest file in JSON format so that you can map the filename you know to the generated one.


Buster needs to know which files you want to fingerprint and where to write a manifest to. You can supply this configuration inside a :buster map like so:

:buster {:files ["resources/public/scripts/awesome.js"]
         :manifest "resources/manifest.json"}

If you're not feeling picky, you can stick that configuration at the project.clj's top level. Otherwise, you can put it at the top level of a relevant profile (example below).

Buster also supplies a hook to run itself post-compile with. You can add that to your project.clj like so:

:hooks [leiningen.buster]

If you're using a hook from another plugin that generates the static files you want fingerprinted (e.g. [lein-cljsbuild] lein-cljsbuild), you should make sure that hook comes before buster's:

:hooks [leiningen.cljsbuild leiningen.buster]


Add [lein-buster "0.1.0"] to the :plugins vector of your project.clj.

You can invoke lein-buster manually from your project like so:

$ lein buster

This is probably not that useful, outside of making sure you've configured things properly. The auto-run configuration outlined above is probably closer to what you're looking for.

If you want to have lein-buster run only as part of your jar compilation (which is likely), your buster config in your project.clj can be nested under the relevant profile like so:

:profiles {:uberjar {:hooks [leiningen.buster]
                     :buster {:files ["resources/public/scripts/awesome.js"]
                              :manifest "resources/manifest.json"}}}


You'll want to parse the generated manifest file and expose the mappings to your views so that you can substitute the file name you know (e.g. application.js) to the fingerprinted version (e.g. application-acbd18db4c.js).

In my current project, we use cheshire to parse the JSON from clojure and construct our views using selmer. We added a custom selmer tag to help with this translation:

(defn load-revision-manifest
  (when-let [manifest (io/resource path)]
    (-> manifest slurp chesh/parse-string)))

(def revision-manifest
  (memoize load-revision-manifest))

;; Returns the fingerprinted asset name for a file listed in the revision manifest.
(selmer/add-tag! :asset-name
                 (fn [args context-map]
                   (let [asset (first args)
                         manifest (revision-manifest "manifest.json")]
                     (or (get manifest asset) asset))))

Subsequent use in a Selmer template looks like this:

<script type="text/javascript" src="/scripts/{% asset-name application.js %}"></script>

If you're using a different templating engine or a completely different approach, please add how you're integrating lein-buster to the wiki!


Copyright © 2016 Stephen Caudill

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.


Generate fingerprinted files from your static assets that are suitable for use in browser cache-busting.







No packages published