What's your advanced cljs repl setup?

I’ve just seen @seancorfield talk REPL-Driven Development: Clojure’s Superpower and it’s great to see a so advanced repl setup like this, but I confess I missed a cljs setup.

Who has an advanced cljs repl setup that would like to share? (Possibly with screenshots)

I’m currently relying a lot in hot reloading with devcards. I’m also using shadow-cljs with vim-fireplace.

1 Like

Not sure this counts as advanced, but at least it covers setting up a ClojureSript REPL.

I’m going to be very interested to see what folks recommend here as I’m just getting back into ClojureScript after a seven-year gap.

What I’ve been experimenting with so far is:

  • write code as .cljc as much as possible including tests
  • evaluate it as if it were Clojure (using my current VS Code/Chlorine/Reveal setup)
  • use Figwheel Main for the cljs-into-the-browser aspect
  • re-frame, cljs-devtools

That lets me use my advanced REPL setup, with code changes automatically recompiled and reloaded into the browser. It’s early days yet – I’ve only been building “toy” stuff – so I’ll be very interested in how folks are doing this where cljs is their day-to-day work.

Some caveats for me:

  • Absolutely must be Clojure CLI based, not Leiningen
  • Absolutely must support Socket REPL, not nREPL

For anyone interested your REPL setup can also mostly be achieved with shadow-cljs. Just add thheller/shadow-cljs to your deps.edn as normal and start your CLJ REPL as you normally would with the socket REPL. From there you can just call

(require '[shadow.cljs.devtools.server :as server])
(require '[shadow.cljs.devtools.api :as shadow])

;; switch REPL to CLJS simply via
;; or
;; or specific to a build configured in shadow-cljs.edn
(shadow/watch :the-build)
(shadow/repl :the-build)

You only need to worry about npm once you want to use actual JS dependencies. Since you mentioned re-frame that would require npm install react react-dom create-react-class. You don’t need to use the actual shadow-cljs CLI interface (from npm). Although that is of course the recommended way to do things.

Note that the above only actually works in a regular Socket REPL. prepl unfortunately has no way to properly “upgrade” a connection from CLJ->CLJS. A prepl you can get via configuring :prepl {:the-build 12345} but that requires running the watch by other means (usually shadow-cljs watch the-build) and then connecting to port 12345 separately.

Not sure how well reveal deals with this though, should be fine with the prepl setup.

Built into shadow-cljs is Inspect which you’ll find at http://localhost:9630/inspect-latest by default. Just (tap> something) in the REPL to see it there. Works for CLJ and CLJS.


As far as I can tell with my experiments with Figwheel Main and re-frame I have managed to avoid Node.js / npm – and I’d like to keep it that way.

I understand that sentiment and if you restrict yourself to only ever using basic react and no third-party JS components that works fine. As soon as you want that you’ll need npm, that is regardless whether it is :target :bundle and figwheel or just shadow-cljs. npm honestly isn’t that bad nowadays. A lot of packages are still not very high quality and packages tend to have a tendency to break stuff but npm itself is not that bad and fairly reliable.