Liking cljdoc? Tell your friends :D

JS Runtime Selection (:js-runtime)

shadow-cljs can use Bun instead of Node.js for running compiled output. This is opt-in per build via the :js-runtime config key.

Supported targets

| Target | Supported | |----------------+--------------| | :node-test | Yes | | :node-script | Yes | | :esm | No (not yet) | | :browser | N/A |

Configuration

Add :js-runtime :bun to a build in shadow-cljs.edn:

{:builds
 {:test
  {:target    :node-test
   :output-to "out/test.js"
   :js-runtime :bun}

  :my-script
  {:target    :node-script
   :main      my.app/main
   :output-to "out/script.js"
   :js-runtime :bun}}}

When omitted, the default is :node (unchanged behavior).

What changes

Autorun tests

With :autorun true on a :node-test build, tests run under bun run <file> instead of node <file>.

Watched builds and REPL

A watched build compiles, and the fork starts no process for it, just as upstream starts none. Whatever runs the output owns that process: bun out/script.js by hand, or a project launcher such as bb dev.

Fork releases before this one started Bun for a watched build carrying :js-runtime :bun. After upgrading, such a build compiles and connects nothing until its output is started, and an eval answers "No available JS runtime".

(shadow/watch :my-script)   ;; compiles; starts nothing
;; then, in a shell: bun out/script.js
(shadow/repl :my-script)    ;; evaluates in the process that connected
  • Start the output only after the watch has printed [:<build>] Build completed. Output left by an earlier watch connects, is rejected as Stale Output!, and stops retrying.
  • The REPL evaluates in whatever connects, however it selected the build: (shadow/repl :id), an editor's nrepl-select (CIDER, Calva, Cursive), the console REPL or shadow/cljs-eval. An eval with no connected runtime fails at once with "No available JS runtime". A tool that evaluates right after starting the watch polls (shadow.cljs.devtools.api/repl-runtimes <build>) until it is non-empty.
  • On a :node-script build the fork only validates :js-runtime. The key records which program runs the output, for tools that start it.

Standalone node-repl

Pass :js-runtime in the options map:

(shadow/node-repl {:js-runtime :bun})

The REPL's build takes its runtime like any other build, so :js-runtime set through :build-defaults or :target-defaults {:node-script …} applies to it as well.

A :node-command option names the program to start and takes precedence over a valid :js-runtime. An invalid :js-runtime still fails the build's config check, so the REPL throws before starting anything.

CLI usage

Pass --js-runtime to any CLI command:

# standalone REPL with Bun
shadow-cljs node-repl --js-runtime bun

# watch, compile or release a :node-test build whose autorun uses Bun
shadow-cljs watch my-tests --js-runtime bun
shadow-cljs compile my-tests --js-runtime bun
shadow-cljs release my-tests --js-runtime bun

The CLI flag overrides :js-runtime in shadow-cljs.edn. What it changes depends on the command:

  • node-repl: the process the REPL starts and evaluates in.
  • watch, compile and release: the runtime a :node-test build's autorun runs its tests under. On a :node-script it changes nothing in the fork.

It is accepted without a warning only on node-family targets (:node-script, :node-test); on other targets it is ignored with a warning.

Requirements

  • Bun must be installed and on PATH
  • Java 21+

Valid values

:js-runtime accepts :node or :bun. On a :node-script or :node-test build, any other value fails the build's config check, and node-repl throws it to its caller before starting a process. Other targets accept any keyword and ignore it with a warning.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close