Fork me on GitHub

Hello. I am using material UI, when use project.clj from luminus template, everything works fine. But I switch to shdow-cljs cli, some component style is not working well. This branch is using lein: and this branch uses shadow-cljs . When click Date Picker or DataGrid, the menu works wrongly.

Shako Farhad10:12:30

Hey guys. I have setup a shadow-cljs project with deps.edn. When I run the

clj -A:shadow-cljs-dev watch app
command I get a server up and running and things are great. But after I quit it with "ctrl + z" the server lingers forever. I can go to localhost:8700 and still see my app running there. If I restart the watch app then it will says that my build is stale and was not produced by the current watcher. Only workaround is to change the port. Anyone know how to fix this? Reboot doesn't help either. So something is cached somewhere? My deps.edn alias:
  {:extra-deps {thheller/shadow-cljs {:mvn/version "RELEASE"}
                re-frame/re-frame {:mvn/version "1.1.2"}
                binaryage/devtools {:mvn/version "1.0.2"}
                re-frisk/re-frisk {:mvn/version "1.3.5" :exclusions [ 
   :main-opts ["-m" "shadow.cljs.devtools.cli"]}
I have manually killed all the processes, rebooted the pc etc. But when I go to localhost:8700, the app is still being served there. And in the corner it says "shadow-cljs reconnecting...". If I try to start a new watch on that same port it will say that it is stale.


Type “fg” will get it back

Shako Farhad13:12:09

just type fg in the terminal? THis waht I tried:

:/mnt/c/bec-core$ fg
-bash: fg: current: no such job
:/mnt/c/bec-core$ npx shadow-cljs fg
shadow-cljs - config: /mnt/c/Users/shako/OneDrive/Documents/GitLab/bec/bec-core/shadow-cljs.edn
shadow-cljs - starting via "clojure"

Invalid action "fg"


fg only works after you ctrl+z a process. it is not a shadow-cljs command, its a linux thing

thheller10:12:47 what do you mean by "shadow-cljs cli"? you should still start the server parts using lein?


no matter server is started by Leon or clj, the result is the same. I’ve compared with both.


I guess there is some thing I did wrong with shadow-cljs. The lein integrated way works fine.


do you get a 404 on some css or so?


css is correctly loaded.


I think there are many problems. Firstly, material UI implement js loaded css, some element will overwrite the global css. Secondly, I do not know why use lein shadow there is no problem, but use shadow-cljs, there are problems. Anyway, I plan not use Material UI now.


I can't do much without a reproducible repo. too many unknown for me. if you set one up I'll take a look and maybe fix it.


Hello @thheller, I put two projects in github: Could you help to have a look? Thanks.


sorry, it was ignored in .gitignore. Now I add it back.


and also package.json is ignored. I add it back also.


$ clj -M:run
Syntax error (FileNotFoundException) compiling at (vorstellung/middleware.clj:1:1).
Could not locate vorstellung/env__init.class, vorstellung/env.clj or vorstellung/env.cljc on classpath.

Full report at:


in the shadow-cljs folder


sorry, please pull again, one config file is missing.


one mistake I see is the deps.edn using :resource-paths. that is not a thing in deps.edn


Thanks. If removed, there is the same problem. I’m just trying every possible solutions..


other than that the only problem I see is that there is a justify-content: center; css rule on one element which causes everything to center


don't know why its there but thats the cause


on .MuiButtonBase-root


so far it looks like everything is working as intended?


If use the shadow-cljs branch, when you click the red menu item, the menu will be in disorder


that is what I mean ...


"disorder" isn't quite right. it is "centered"


Yes, centered and shrinked a little


Three button over the table “load, send and export” is also turn to white. It is blue in lein-shadow branch.


If comment the table in src/cljs/vortellung/app/table.cljs: #_[people] everything turns OK


or this part:


clojure #_[:> m/TableContainer {:style {:height "80vh", :width "auto"}} [:> dg/DataGrid {:rows rows :columns cols :checkboxSelection true :autoPageSize true :exportAllData true}]]```


the lein run doesn't work at all for me


I get some swagger stuff


ah nevermind. I guess because the js is missing


In lein-shadow branch, if lein run not work, you can use clj -M:run also. and use lein shadow watch home app


why are home and app two builds?


home build contains some authentification stuffs. But I removed in these two sample.


I'm sorry but I really can't tell what is going on in this template at all


waaaaaaaaaaaaaaay to much other stuff I can't look at


the CLJS parts look fine but the CLJ server parts I can't figure out


But If CLJ server is running with clj -M:run it should be same as shadow-cljs branch..


So far as I know, the only different is the way to run shadow-cljs, with lein shadow or with shadow-cljs .


I try to reproduce the issue after remove the backend and some unrelated codes.


Hello @thheller, I simplify the code in the same repo, could you help to have a look? Thanks:


can you get rid of all the server-side code and just use :dev-http static webserver? the server parts are the confusing bits for me


I don’t how to create client only SPA. Thank you for your reminds. I will try :dev-http


you just take out everything that talks to the server


Server parts are removed now.


so I upgraded the shadow-cljs version in lein-shadow to 2.11.10 so both variants use the same version


and they look exactly the same then


you can add :js-options {:entry-keys ["browser" "main"]} to your build config which appears to make it work

👍 3

why I can't quite tell. looks like something in material-ui behaves differently when using "module" as well


Thank you. I just realized that these two branches use different version of shadow-cljs, sorry for this.


:js-options {:entry-keys ["browser" "main"]} solve this issue. That’s great!


you should maybe consider removing this and just requiring all the esm code directly


otherwise you end up with a weird mix of commonjs and esm


material ui is one of those packages that contains 15 different variants on the code in one package


basically you just add an esm path to all requires


so isntead of ["@material-ui/icons/Build" :default Build] you use ["@material-ui/icons/esm/Build" :default Build]


OK, I will try this solution. Thanks very much.


this way is not working: `["@material-ui/icons/Build" :default Build]` to `["@material-ui/icons/esm/Build" :default Build]`


sorry no time to look into this today. guess the old way is fine then.


Yes. :js-options {:entry-keys ["browser" "main"]} this way is fine now. Thank you for your time. It helps a lot.


@shakof91 ctrl+z sends the process to the background and keeps it running, ctrl+c stops it.

Shako Farhad10:12:22

It has the same behaviour. The page is stuck at "shadow-cljs - reconnecting ..." instead of showing a blank page after I run "ctrl + c". This is what I see in the console. In addition a lot of sourcemap warning spam comes too.

shadow.cljs.devtools.client.websocket.js:sourcemap:4 WebSocket connection to '' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
shadow$cljs$devtools$client$websocket$start @ shadow.cljs.devtools.client.websocket.js:sourcemap:4
eval @ shadow.cljs.devtools.client.shared.js:sourcemap:467
shadow$cljs$devtools$client$shared$init_runtime_BANG_ @ shadow.cljs.devtools.client.shared.js:sourcemap:929
eval @ shadow.cljs.devtools.client.browser.js:sourcemap:952
goog.globalEval @ app.js:577
env.evalLoad @ app.js:1670
(anonymous) @ app.js:1945
shadow.cljs.devtools.client.shared.js:sourcemap:651 shadow-cljs - remote-error Event {isTrusted: true, type: "error", target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …}
This wouldn't be a problem if I could run the watch command again and just be able to continue developement from the same port again, but I instead get this message: "Shadow-cljs - stale output! Your loaded js was not produced by the running shadow-cjs instance. Is the watch running?" Even if I try to delete the .shadow-cljs folder, the .cpcache folder and remove the app.js files, it will still say this as long as I use the same port.


I don't understand your issue. what do you expect?


the server started by lein is serving the content. shadow-cljs just produces the javascript and it needs to be running for that JS to connect back


don't start 2 shadow-cljs instances for the project or you will get a mess

Shako Farhad10:12:33

My expectation is that I can stop the watch and restart it later. So maybe I am not understanding how to start and stop it. I thought it was just to stop it with ctrl + c and run it again with "clj -A:shadow-cljs-dev watch app" again.

Shako Farhad10:12:18

I am also expecting that the websocket will stop when I run ctrl + c so that the browser doesnt show my app anymore. I have disabled caching in the browser as well so I would expect that the app wouldn't linger when I go to localhost:8700 after I have stopped it. :x


what commands do you run exactly? I mean to me it sounds like you just have 2 instances running


first check there is actually only one instance running. you can check how many instances via jps or so

Shako Farhad10:12:18

  "name": "bec-core",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "watch-app": "clj -A:shadow-cljs-dev watch app",
    "release-app": "clj -A:shadow-cljs-prod release app",
    "cljs-repl": "clj -A:shadow-cljs-dev cljs-repl app"
  "dependencies": {
    "react": "16.13.0",
    "react-dom": "16.13.0"
That is my package.json and I run
npm run watch-app
It builds etc just fine and then I press "ctrl + c"


and what do you get?


there should be a "server shutdown" message

Shako Farhad10:12:09

shako$ npm run watch-app

> [email protected] watch-app
> clj -A:shadow-cljs-dev watch app

shadow-cljs - HTTP server available at 
shadow-cljs - server version: 2.11.8 running at 
shadow-cljs - nREPL server started on port 52471
shadow-cljs - watching build :app
[:app] Configuring build.
[:app] Compiling ...
[:app] Build completed. (268 files, 0 compiled, 0 warnings, 5.22s)
Worker shutdown.


thats just the worker not the server


try jps to see if there is a running java process

Shako Farhad10:12:37

shako$ jps
7582 Jps
shako$ jps -l
7600 jdk.jcmd/
I haven't used jps before. I am not exactly sure what to expect. :x

Shako Farhad10:12:50

I ran the jps command in the windows terminal instead of the WSL2 ubuntu terminal:

12576 RemoteMavenServer36
18528 Jps
17028 RemoteMavenServer36
3204 RemoteMavenServer36
5796 RemoteMavenServer36
6472 RemoteMavenServer36
12908 RemoteMavenServer36
14380 RemoteMavenServer36
12592 RemoteMavenServer36
3408 RemoteMavenServer36
8592 RemoteMavenServer36
11316 RemoteMavenServer36
10552 RemoteMavenServer36
3672 RemoteMavenServer36
13212 RemoteMavenServer36

Shako Farhad10:12:05

THis is the culprit huh? 😄

Shako Farhad10:12:47

C:>jps -l
12576 org.jetbrains.idea.maven.server.RemoteMavenServer36
17028 org.jetbrains.idea.maven.server.RemoteMavenServer36
3204 org.jetbrains.idea.maven.server.RemoteMavenServer36
5796 org.jetbrains.idea.maven.server.RemoteMavenServer36
6472 org.jetbrains.idea.maven.server.RemoteMavenServer36
12908 org.jetbrains.idea.maven.server.RemoteMavenServer36
14380 org.jetbrains.idea.maven.server.RemoteMavenServer36
12592 org.jetbrains.idea.maven.server.RemoteMavenServer36
3408 org.jetbrains.idea.maven.server.RemoteMavenServer36
8592 org.jetbrains.idea.maven.server.RemoteMavenServer36
11316 org.jetbrains.idea.maven.server.RemoteMavenServer36
22100 jdk.jcmd/
10552 org.jetbrains.idea.maven.server.RemoteMavenServer36
3672 org.jetbrains.idea.maven.server.RemoteMavenServer36
13212 org.jetbrains.idea.maven.server.RemoteMavenServer36

Shako Farhad10:12:22

Looks like intellij processes, right?


might be the 16336?


check with regular ps or so


you are using npm and clj and either of those may be causing the server to linger. I can't say. I can only help with actual running shadow-cljs commands


any reason you are not using the shadow-cljs command?

Shako Farhad11:12:57

We are trying to use deps.edn for the dependancy management and the recommended way was to use the clj -A:alias watch app command to run shadow-cljs through the shadow-cljs.devtools.cli.


no that isn't recommended anywhere


you can still use deps.edn to manage dependencies. that is totally fine.

Shako Farhad11:12:37

Running with clj directly.

{:paths [...]
 :deps {...}
  {:extra-deps {thheller/shadow-cljs {:mvn/version <latest>}}
   :main-opts ["-m" "shadow.cljs.devtools.cli"]}}}
clj -A:shadow-cljs watch app
Is what I followed in the documentation. Perhaps I am just too noob to know how to properly setup and run with deps.edn :s


that is meant as an example that you CAN run with clj directly. doesn't mean you should.


it is completely fine to do this. I just can't help you with debugging issues then 😛


you should run the regular shadow-cljs watch app and so on


I guess I should clarify that in the docs

Shako Farhad11:12:57

How can I setup dev dependancies and prod dependancies when using deps.edn and shadow-cljs installed globally? 😮


you don't have to in CLJS


just keep everything on the classpath all the time

Shako Farhad12:12:02

I am sorry I am really noob at this. What exactly do you mean? Just ignore deps.edn and let shadow-cljs handle the deps? This is how I have set it up: deps.edn

{:paths ["src" "resources" "target"]

 {org.clojure/clojure {:mvn/version "1.10.1"}}

  {:extra-deps {thheller/shadow-cljs {:mvn/version "RELEASE"}
                re-frame/re-frame {:mvn/version "1.1.2"}
                binaryage/devtools {:mvn/version "1.0.2"}
                re-frisk/re-frisk {:mvn/version "1.3.5" :exclusions [
{:deps {:aliases [:cljs]}

  {:target :browser
   :output-dir "resources/public/js"
   :modules {:app {:entries [bec-core.cljs.core]}}

   :js-options {:js-package-dirs ["node_modules"]}

   :compiler-options {:infer-externs :auto}

   :dev {:closure-defines {goog.DEBUG true}}
   {:before-load bec-core.cljs.core/stop
    :after-load bec-core.cljs.core/start
    :http-root    "resources/public"
    :http-port    8711
    :preloads     [devtools.preload
Running it like this:
$ npx shadow-cljs watch app
shadow-cljs - config: /mnt/c/Users/shako/OneDrive/Documents/GitLab/bec/bec-core/shadow-cljs.edn
shadow-cljs - starting via "clojure"
shadow-cljs - HTTP server available at 
shadow-cljs - server version: 2.11.8 running at 
shadow-cljs - nREPL server started on port 60273
shadow-cljs - watching build :app
[:app] Configuring build.
[:app] Compiling ...
[:app] Build completed. (270 files, 59 compiled, 0 warnings, 24.61s)
$ Worker shutdown.
npx shadow-cljs stop app
shadow-cljs - config: /mnt/c/Users/shako/OneDrive/Documents/GitLab/bec/bec-core/shadow-cljs.edn
shadow-cljs - server not running
I don't know how to exlude refrisk and dev-tools dependancies from the release version of the app. Also even when I run shadow-cljs through npx it still has the same issue. I can't stop the server with ctrl + c. The browser still shows the old app running and a new watch on the same port won't update anymore. It will just ocmplain about a stale build.. 😕


you don't need to exclude dev stuff from release. shadow-cljs only includes what you actually require in your code in the build


so it absolutely does not matter if devtools and refrisk are on the classpath for release builds

Shako Farhad13:12:58

Ah I understand! Wow that is smart! 😄


you also don't need these

:js-options {:js-package-dirs ["node_modules"]}

   :compiler-options {:infer-externs :auto}

   :dev {:closure-defines {goog.DEBUG true}}


those are already the defaults


I don't have a clue why you can't stop the server via ctrl+c. which OS is this?


which clojure version?

Shako Farhad13:12:02

I am running on windows 10 in WSL2 ubuntu terminal.

$ clj --help


so if you just run shadow-cljs server and ctrl+c that the process still lingers?

Shako Farhad13:12:15

$ npx shadow-cljs server
shadow-cljs - config: /mnt/c/Users/shako/OneDrive/Documents/GitLab/bec/bec-core/shadow-cljs.edn
shadow-cljs - starting via "clojure"
shadow-cljs - HTTP server available at 
shadow-cljs - server version: 2.11.8 running at 
shadow-cljs - nREPL server started on port 50490
THe page at http://localhost:9630 dissappears when I reload it. So it works as expected when I ctrl + c. But http://localhost:8712 is still there. "Shadow-cljs - reconnecting..." And when I start the server the message just becomes "Shadow-cljs stale build etc."

Shako Farhad13:12:48

Windows terminal result:

C:\bec-core>jps -l
10088 jdk.jcmd/
Ubuntu terminal result:
bec-core$ jps -l
9068 jdk.jcmd/


if you start it in wsl2 then only that matters. the windows side doesn't matter at all.


can't mix them

Shako Farhad13:12:27

Alright. All commands are run in WSL2. I don't have clojure installed on windows 10, only in WSL2.


get your system into a state where serves nothing

Shako Farhad13:12:59

Yes, I am trying the best I can. I even rebooted the machine and it still is there :s


ok that is definitely not shadow-cljs then


maybe you have some other server running there or some cache stuff I don't know

Shako Farhad13:12:22

My app starts a service worker to register the app. Is it perhaps that which is causing it to not let go?

Shako Farhad13:12:44

Yep. Now it behaves as expected! I removed this piece of the code:

    (-> (. js/navigator.serviceWorker (register "/service-worker.js"))
      (.then (fn [] (js/console.log "service worker registered"))))

    (catch js/Object err (js/console.error "Failed to register service worker" err)))
And now the browser is properly letting go. So it is probably a chrome issue. I wonder how to fix it...


ah you used a service worker ... yeah you shouldn't cache the output of a watch build ever. just disable that in the worker.

Shako Farhad13:12:06

Is it possible to output the release version to a different directory than the watch build output? I could then set the service worker to cache the release version only? Or perhaps the right way to do this is to register the service worker in release mode only, using the goog.DEBUG to toggle the registering of the service worker... Not sure what is best to do 😮

Shako Farhad13:12:57

One solution for now is to just clear the service-worker cache: inspect -> application -> clear storage


:release {:output-dir "somewhere/else"}

Shako Farhad13:12:06

Ah! THat is wonderful! Thank you! I understand now. I am sorry for taking so much of your time. I appreciate your help!

Michaël Salihi14:12:37

Hello @thheller Since your proposition was not seleted, I wonder to know how to do without the convenient Shadow-CLJS's :default on vanilla CLJS.

Michaël Salihi14:12:10

Hasn't that changed since the issue?


(:require ["foo$default" :as x]) will be the default solution but I don't think it is released yet


vs (:require ["foo" :default x]). you can also always do (:require ["foo" :as x]) and then x/default

Michaël Salihi14:12:46

I just test with Krell and this don't works with this RN lib I'll try with RN Shadow-CJLS and see if it comes from the lib which may be specific.

Michaël Salihi15:12:48

@thheller So I just tried with Shadow-CLJS and your "reagent-react-native" repo.

    [shadow.react-native :refer (render-root)]
    ["react-native" :as rn]
    ["react" :as react]
    [reagent.core :as r]
    ["react-native-alarm-clock" :default AlarmClock]))

(defn create []
  (let [date (.toISOString (js/Date.))]
    (.createAlarm AlarmClock date "Alarm test")))

Michaël Salihi15:12:26

And I have this error

Michaël Salihi15:12:30

A little idea @thheller please?


I don't have a clue. it might be ["react-native-alarm-clock" :as AlarmClock]?


default exports are tricky sometimes because it also depends on how the library is bundled. looking at the code does not always match what the actual published package uses.

Michaël Salihi16:12:54

OK, I can see the published package provides 3 versions

Michaël Salihi16:12:11

How does CLJS do in this case?

Michaël Salihi16:12:18

CommonJS take predecence?

Michaël Salihi16:12:57

@thheller I think I have a lead. The CommonJS and module version export this var _default

Michaël Salihi16:12:01

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
exports.default = void 0;

var _reactNative = require("react-native");

const {
} = _reactNative.NativeModules;
var _default = AlarmClock;
exports.default = _default;


yes it is in master. just not in any official release I think.

👍 3

Hey @thheller could you please explain how shadow-cljs compiles dependencies? Users declare dependencies, you fetch them using aether... and then? How do the .cljc bits make it into the JS source code?


I've been trying to read the source of shadow-cljs but couldn't find where this magic happens


not sure I understand the question


.cljc files are just source code somewhere on the classpath


so if you require the somewhere in your code


it'll look for foo/bar.cljs or foo/bar.cljc


then it compiles those. code is in


But how do you acquire the cljc out of the jars? Do the jars contain the raw cljc files?


the files are loaded via ( "foo/bar.cljc")


doesn't matter if its a regular file or in a jar. jvm classloader handles that.


So basically you have maven (aether) fetch the jars (and unpack them?) then collect all the cljc/cljs files and give them to the compiler?


The CLJS compiler can walk into jars?


it doesn't have to. the jvm classloader does.


jars are never unpacked (on disk, happens all in memory only)


Ohh I see, jvm magic! Does the CLJS compiler look for cljs/cljc files on its own or do you have to feed it the files "manually"?


shadow-cljs will load and read them


Awesome, I understand! Thanks a lot!


@thheller looks like might be down? Not loading for me.


I think it's during migrating.


is there a way to get browser tests to pretty-print failures, so that they're not all on one line like this? I'm guessing I would need a custom :ns-runner but beyond that it's hazy...


i think that's the output from @bhauman’s excellent cljs-test-display


Checking that out, thanks for the tip!