Beginner guide to compile ClojureScript to CommonJS and use Webpack

shadow-cljs is a ClojureScript compiler which friendly to JavaScript developers.

By default, ClojureScript code is compiled to JavaScript in Google Closure Compiler modules, which uses namespaces to manage files(or modules). However, nowadays the JavaScript community has changed a lot since the year Google Closure Compiler was born. We used CommonJS and will use ES6 modules for numerous JavaScript modules on npm.

Meanwhile, in order to reuse our knowledge from Webpack, the shortest path is to compile ClojureScript to CommonJS or ES6 code that Webpack consumes. And shadow-cljs can do it.

To install shadow-cljs, you need to Node.js installed, then you can use npm. Say we are using macOS:

brew install nodejs
npm install -g shadow-cljs

To run shadow-cljs, a configuration file called shadow-cljs.edn is required:

{:source-paths ["src"]
 :dependencies [[mvc-works/hsl "0.1.2"]]
 :builds {:app {:target :npm-module
                :output-dir "compiled/"}}}

In this example,

  • source-paths is where we put source code
  • dependencies, well…
  • builds is a map with build ids and build configurations, and currently the build-id is :app.
  • target specifies which platform(or usage) the code is compiled:
    • :npm-module stands for CommonJS modules
    • :browser stands for web browsers
    • :node-script stands for a standalone Node.js script
  • output-dir is where the code is emitted to

Then, to compile ClojureScript in src/ to JavaScript in CommonJS to compiled/, just run the build-id called :app:

shadow-cljs compile app

It should work now. You may also need to check the full example here:

And to learn more about how to use shadow-cljs, please take a look that the README and Wiki pages of shadow-cljs:

If you got and thoughts, please share with use on Slack or fire Issues.


Wow, I saw someone just clicked this topic. This post is really old. shadow-cljs might be release tens of versions since then. I’m not using :target :npm-module today since shadow-cljs offered better experience import npm modules after that. I’m curious is anyone still using this :target today?

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.