ClojureScript for web development - where to start? (AKA Little Printf [1])

Having already some Clojure experience and feeling sort of comfortable with it, I wanted to try some „modern” web development - in the end it’s quite useful to be able to work on both backend and frontend…

As a „starting point” I selected I want to learn how to create React site.

I’ve started looking at ClojureScript and there were (at least) two choices - Reagent and Om. After playing with reagent, being terrified by 117 lines of autogenerated project.clj which I won’t be ever able to reproduce by hand I realized that I have no idea how to use RandomNodeJsModule from NPM - and this makes, as far as my understanding goes, whole investment worthless.

So I’ve googled about „ClojureScript and nodejs”. OK, nice. Sort of. For my inexperienced eye it seems like it adds even more of boilerplate.

Then, on IRC, I was told about Lumo - and now I am lost.

So here comes my dumb question. I know and like Clojure and I’d like to create modern webapps with NodeJS, React and all the NPM goodies ready to be reused to be capable of „Full Stack development”. How do I? Which way to go? When company X is looking for fullstack clojure dev with React, what are they using?

Thank for all the advices.

[1] (chapter 7)

1 Like

If you want to use npm modules easily, I’d advise checking out shadow-cljs. It is a replacement for lein, but focuses exclusively on easy integration with JavaScript ecosystem.

If you want to use react, I’d advise checking out example app of re-frame or keechma. Both are libraries that give you some structure for building your app.

Keechma is what I am using, and it is awesome, but if you are just starting out with Clojurescript re-frame might be a better starting point.

Let me know if you have any questions.


I really do appreciate our reply. Thank you!

I never heard about shadow-cljs. After reading about it briefly, I understand it as Leiningen replacement, crafted specifically for ClojureScript (maybe it is trying to address problems like mine, where for ClojureScript user was enforced to use extensive boilerplate in Lein?).

Unfortunately, shadow-cljs adds also (another) bit of confusion. With it, where does previously advertised Lumo stands relatively to it? How I feel right now is that:

  1. There is Lumo and it… ok I don’t get it.

Could you please clarify for me where does all of shadow-cljs, leiningen, lumo (and I see some planck also!) and reagent plus SomeRandomLibrary from stand in relation to each other?

Still - thanks for shadow-cljs, as now I have some point of reference in which (new) direction to dig!

Hello there. I’m the author of shadow-cljs so maybe I can shed some light on how it all fits into this.

shadow-cljs is mainly intended as a standalone build tool aimed at JS developers that are not familiar with the Clojure ecosystem and have never used either lein or the others at all. So by default you use it as any other npm or node related tool. Basically you just npm install shadow-cljs to start using it. It trades having to know lein to having to know npm basically. It is however built as a normal Clojure lib as well so using it via lein is possible as well.

Another goal of shadow-cljs is removing as much of the boilerplate configuration as possible. So equal configs will usually be at least 50% smaller.

I usually recommend running shadow-cljs standalone side-by-side with your normal Clojure setup. Embedded works fine for many but it does require some extra care to avoid certain problem (eg. dependency conflicts). Besides that build configuration is the same whether you use lein or not. The only difference is whether you put your CLJS deps into project.clj or shadow-cljs.edn.

lumo is also a standalone CLJS tool distributed via npm. The main difference is that lumo uses the self-hosted CLJS compiler and does not require java at all. It is missing many important build features and is generally intended to build small command line “scripts” rather than full applications. Or at most pure node applications, ie. not browser targeted apps.

planck is similar to lumo and intended for scripts as well. It uses JavascriptCore and does not require node/npm.

reagent is a wrapper for the popular react npm library providing a more clojure-ish interface.

SomeRandomLibrary from npm is just some dependency like any other CLJS dependency. With shadow-cljs you can use them directly without any other configuration. Just npm install SomeRandomLibrary and (:require ["SomeRandomLibrary" :as lib]) to get going. The npm support in CLJS is still very experimental and shadow-cljs replaces that with a more reliable custom solution.


Could you please clarify for me where does all of shadow-cljs, leiningen, lumo (and I see some planck also!) and reagent plus npm stand in relation to each other?

I think I can provide an inaccurate but short version of the relationships among them.

  1. At first Clojure used Maven for building.
  2. Maven is boring, people made Leiningen, configuring with maps, and the plugin lein-cljsbuild can build ClojureScript.
  3. Leiningen contains only configurations, no logics. People want to compose tasks, so they made Boot, and provided boot-cljs and boot-reload for ClojureScript.
  4. Webpack is cool with hot module replacement, we got lein-figwheel for that.
  5. All tools above relies on JVM heavily, in order to run ClojureScript on devices without JVM, like iOS, Planck was created based on self-hosted ClojureScript and JavaScriptCode, which is a ClojureScript runtime.
  6. Planck does not support modules from npm, then Lumo was created to make full use of V8 engine.
  7. We still feel the toolchain is too heavy for developers from JavaScript ecosystem, shadow-cljs was refactored to be more friendly, supporting npm modules, relies on JVM but in the background, also with some features from Webpack.
  8. in the meantime, offciial cljs compiler is still improving…

The situation today is more history than design.


Thank you for all your replies! I am now able to make a decision and go for shadow-cljs at this moment.

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