Skip to content
ClojureScript compilation made easy
Clojure JavaScript Java Other
Branch: master
Clone or download

Latest commit

thheller remove cljs.test hack
cljs 1.10.773 included patch that does this properly
Latest commit d80ee47 May 26, 2020


Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci fix CI build Aug 17, 2018
.github enable github sponsors? Oct 18, 2019
doc [WIP] first preview of shadow.remote Oct 22, 2019
externs consider simplified externs before warning about :infer-externs Nov 30, 2018
out add basic graaljs target Apr 20, 2020
packages bump 2.9.10 May 26, 2020
src remove cljs.test hack May 26, 2020
test-env default to fail on asset require May 6, 2020
test-project experimental CLJS-3235 support May 24, 2020
test rewrite Buffer/__filename/__dirname uses to match webpack/browserify Jul 4, 2018
.gitignore fix goog.module loading errors in react-native dev builds Feb 27, 2019 bump Oct 19, 2017 small doc tweak Apr 21, 2018
LICENSE split out of shadow-build, too many deps Oct 9, 2015 Update (#663) Apr 4, 2020 use a more robust way to launch external processes (hopefully) Oct 17, 2018 fix file perms, resize icon for osx Oct 10, 2018 fix file perms, resize icon for osx Oct 10, 2018
deps.edn Fix typo in deps.edn. (#699) May 6, 2020
karma.conf.js :target :karma, still needs work but functional Nov 23, 2017
npm-run.js fix proc.kill on windows Oct 2, 2018
project.clj bump cljs May 26, 2020
shadow-cljs.edn experimental way to auto-add namespaces to build May 26, 2020

shadow-cljs provides everything you need to compile your ClojureScript code with a focus on simplicity and ease of use.

npm Clojars Project


  • Good configuration defaults so you don't have to sweat the details
  • Seamless npm integration
  • Fast builds, reliable caching, ...
  • Supporting various targets :browser, :node-script, :npm-module, :react-native, :chrome-extension, ...
  • Live Reload (CLJS + CSS)
  • Code splitting (via :modules)



  • node.js (v6.0.0+, most recent version preferred)
  • npm (comes bundled with node.js) or yarn
  • Java SDK (Version 8+, Hotspot)

Quick Start

Creating your project can be done quickly using the npx create-cljs-project utility. npx is part of npm and lets us run utility scripts quickly without worrying about installing them first. The installer will create a basic project scaffold and install the latest version of shadow-cljs in the project.

$ npx create-cljs-project acme-app
npx: installed 1 in 5.887s
shadow-cljs - creating project: .../acme-app
Creating: .../acme-app/package.json
Creating: .../acme-app/shadow-cljs.edn
Creating: .../acme-app/.gitignore
Creating: .../acme-app/src/main
Creating: .../acme-app/src/test
Installing shadow-cljs in project.

npm notice created a lockfile as package-lock.json. You should commit this file.
+ shadow-cljs@<version>
added 88 packages from 103 contributors and audited 636 packages in 6.287s
found 0 vulnerabilities


The resulting project has the following structure

├── node_modules (omitted ...)
├── package.json
├── package-lock.json
├── shadow-cljs.edn
└── src
    ├── main
    └── test

shadow-cljs.edn will be used to configure your CLJS builds and CLJS dependencies. package.json is used by npm to manage JS dependencies.

Everything is ready to go if you just want to start playing with a REPL

$ npx shadow-cljs node-repl
# or
$ npx shadow-cljs browser-repl

When building actual projects we need to configure the build first and create at least one source file.

The default source paths are configured to use src/main as the primary source directory. It is recommended to follow the Java Naming Conventions to organize your CLJS namespaces. It is recommended to start all namespaces with a unique enough prefix (eg. company name, project name) to avoid conflicts with generic names such as app.core. Suppose you were building a Web Frontend for Acme Inc. using might be a good starting point as it can easily grow to include acme.backend.* later on.

Using the above example the expected filename for is src/main/acme/frontend/app.cljs.

Lets start with a simple example for a browser-based build.


(defn init []
  (println "Hello World"))

Inside the shadow-cljs.edn :builds section add

  {:target :browser
   :modules {:main {:init-fn}}

This config tells the compiler to call ( when the generated JS code is loaded. Since no :output-dir is configured the default public/js is used. You can start the development process by running:

$ npx shadow-cljs watch frontend
a few moments later ...
[:frontend] Build completed. (134 files, 35 compiled, 0 warnings, 5.80s)

The compilation will create the public/js/main.js we configured above (:main becomes main.js in the :output-dir). Since we want to load this in the browser we need to create a HTML file in public/index.html.

<!doctype html>
    <meta charset="utf-8" />
    <title>acme frontend</title>
    <div id="root"></div>
    <script src="/js/main.js"></script>

We also need a simple HTTP server to serve our HTML since modern Browsers all place a few restrictions on files loaded directly from disk which will lead to issues later. shadow-cljs provides such a server but you can use anything you like at this point. It only matters that the files from the public directory are served properly. To start the built-in web server just adjust the build config from above.

 :dev-http {8080 "public"}
  {:target :browser
   :modules {:main {:init-fn}}

Once the config is saved the server will automatically start and serve the content at http://localhost:8080. There is no need to restart shadow-cljs. When opening the above URL the Browser Console should show "Hello World".

To be continued ...


Please refer to the User Manual. (Work in Progress)

Video Courses





Copyright © 2020 Thomas Heller

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

You can’t perform that action at this time.