Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Tools by
edited by

Hi everyone, I’ve gone through the shadow-cljs quickstart guide in the GitHub repo README and got the desired message in the browser console. Next, I wanted to introduce deps.edn to the project. I had some (self-inflicted) difficulty in jacking in after adding deps.edn.

System details:
Java version: OpenJDK 11.0.15
Clojure CLI version:

With only shadow-cljs.edn in the project, said file contents are:

;; shadow-cljs.edn
{:source-paths ["src/dev"
 :dependencies []
 :dev-http {8080 "public"}
 :builds {:frontend {:target :browser
                     :modules {:main {:init-fn acme.frontend.app/init}}}}}

At this point, jacking in with Calva using the “shadow-cljs” project type, which both starts and connects to the “:frontend” build, works like a charm.

As mentioned in the first paragraph, I had difficulty with introducing deps.edn to the project.

Add deps.edn to the main project directory with the following contents:

;; deps.edn
{:paths ["src/main"

 {:cljs {:extra-deps {thheller/shadow-cljs {:mvn/version "2.19.0"}}}}}

Change shadow-cljs.edn to:

 ;; shadow-cljs.edn
 {:deps {:aliases [:cljs]}
:dev-http {8080 "public"}
:builds {:frontend {:target :browser
:modules {:main {:init-fn acme.frontend.app/init}}}}}

Jacking in with Calva using the “deps.edn + shadow-cljs” project type at this point leads to an error containing “Failed starting cljs repl for build: :frontend. Is the build running and connected?”

The Calva Connection Log also provides information, including: “shadow-cljs has not been started yet!” and “If you have a shadow-cljs server or watch running then you are not connected to that process.”

The build doesn’t seem to have been started. What if we run npx shadow-cljs watch frontend and then tried connecting to the REPL? Same error messages as before.

It turns out I should’ve instead kept using the “shadow-cljs” project type (in which case the addition of deps.edn goes down without a hitch).

This leads me to wonder:

  • When to use which project type?
  • Which is preferred for a fullstack

Thanks to Peter and contributors for Calva!

1 Answer

+2 votes

Hi there! Thanks for asking about this. The naming of these project types in Calva is a bit confusing, even if I don't really know what else to name them. Which project type to use depends on how the project is configured.

A shadow-cljs project can be configured so that you can start it with either shadow-cljs or with deps.edn. Most often just one of them is used. This is not Calva specific, but rather just about how the project is supposed to be started. The Calva project types are configurations + some code that will start the project.

The shadow-cljs project type starts the development REPL with a command line like:

npx shadow-cljs watch -d cider/cider-nrepl:0.27.4  <build-id-1> [<build-id-2> ...]

This is how you have configured your project above to be started, so that's why this works.

The deps.edn + shadow-cljs project type starte the REPL with a command line like:

clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version,"0.9.0"},cider/cider-nrepl {:mvn/version,"0.27.4"}}}' -M<alias-1>[<alias-2>...] -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]"

I can't recall right now what is needed in deps.edn for this to work, but anyway, there needs to be things there to support this. (Some :main config that will start the shadow-cljs watcher.) Your project is not configured for it, which is why the that project type doesn't work. (Calva error handling here is not good, so you do not get proper messages about what goes wrong.)

In both cases, once the Clojure REPL is started, Calva will:

  1. Connect to this REPL.
  2. Clone the nREPL (the protocol used for the REPL connection) session. This is the Calva clj session and will be used in .clj files, as well is .cljc files when Calva is configured to do that. (This is a toggle, which you can access via the status bar.)
  3. Make yet another clone of the nREPL session. This will be the Calva cljs session and be used with .cljs files, and for .cljc files depending on that toggle.
  4. ”Promote” the cljs session to a ClojureScript REPL. Calva uses the shadow-cljs development API for this. The same commands as you would from the REPL prompt if you did this from a terminal.
  5. Select one of the builds watched. Again using the shadow-cljs development API

Note that outside of Calva you can do these steps manually. I can recommend to do it now and then to de-mystify what Calva does at Jack-in and connect. But when connecting Calva, better let Calva do it, because Calva will then be able to update some of its state, so that the UI reflects which REPL is being used and such.

This answers, I hope, when to select which project type in Calva.

You are rather asking about when to use one or the other project setup. I'll let other people answer that, because it is outside my field of expertise. But I can say that I prefer to try use shadow-cljs for starting the dev REPL. I think that most often works.