shadow-cljs is a comprehensive ClojureScript compiler and JavaScript bundler that simplifies the development workflow for ClojureScript projects. It offers fast incremental compilation, robust hot-reloading for both ClojureScript and CSS, and seamless integration with the broader JavaScript ecosystem, including npm packages and various build targets (e.g., browser, Node.js, React Native, Chrome extensions). The current stable version is 3.4.4, with point releases occurring frequently to address bugs and introduce minor features, ensuring an active and responsive development cycle. A key differentiator is its focus on providing sensible defaults and abstracting away complex configurations, offering a highly optimized developer experience for both development and release builds, particularly for projects heavily utilizing npm dependencies, contrasting with tools like Figwheel-main which are often preferred for purely ClojureScript projects.
npm install shadow-cljsVerified import paths — ran on the pinned version, not inferred.
Demonstrates how to scaffold a new shadow-cljs project, configure a basic browser build, create a sample ClojureScript application with Reagent, and run the development watcher.
Upgrade your Java Development Kit (JDK) to version 21 or later. Review your `shadow-cljs.edn` configuration for deprecated options and adjust polyfill strategies if `node-libs-browser` was explicitly relied upon.
It is strongly recommended to let `shadow-cljs` manage its internal dependencies. If conflicts arise, check the `shadow-cljs` changelog and `clojars` for the exact dependency versions it uses and align your project's `project.clj` or `deps.edn` to match, or use `shadow-cljs.edn` exclusively for dependency management where possible to leverage its internal checks.
Instead of relying on automatic installation, you must manually trigger the `npm-deps` installer using `npx shadow-cljs run shadow.cljs.npm-deps` (or the `clj -X` or `lein run` equivalents) when your dependencies change.
Configure `shadow-cljs` to use a polling-based file watcher by setting `:fs-watch {:impl :polling}` in your `shadow-cljs.edn` configuration or via the `SHADOW_CLJS` environment variable. This is more resource-intensive but ensures changes are detected in containerized setups.If encountering parsing errors with modern JS libraries, consider using an external JavaScript bundler like ESBuild (via a `shadow-cljs` hook or manual step) to pre-process problematic JavaScript dependencies before `shadow-cljs` compiles your ClojureScript.
Pre-process the problematic JavaScript library using another bundler (e.g., ESBuild, Babel) before `shadow-cljs` compilation, or configure `shadow-cljs` to exclude the parsing of that specific file if it's not directly needed for ClojureScript compilation.
Ensure the `shadow-cljs watch <build-id>` command is running in your terminal and has successfully completed its initial compilation before refreshing the browser or running the Node.js application. Avoid opening the build target URL before compilation is complete.
For browser builds, ensure your HTML page loads the compiled JavaScript file (e.g., `public/js/main.js`). For Node.js builds, ensure your Node.js process requires the compiled output (e.g., `node -e 'require("./dist/index.js")'`) after starting `shadow-cljs node-repl <build-id>`.Check your `project.clj` or `deps.edn` for `org.clojure/clojure`, `org.clojure/clojurescript`, and `com.google.javascript/closure-compiler-unshaded` versions. Ensure they match what `shadow-cljs` expects (consult its `clojars` dependencies for the exact versions for your `shadow-cljs` version). Consider using `shadow-cljs.edn` for all dependency management to simplify this.