Fork me on GitHub

I have a question regarding to clojure.spec, how is it integrated with shadow-cljs? can It have a different run command? like npm test ? how do you setup the files with it? is there an example ?

Andy Heywood09:05:17

The question’s a bit confusing, that’s not really how spec works - but it exists for cljs in the same way as it does for clojure.

Andy Heywood09:05:22

I’ve been working with it over the last few days - just require cljs.spec.alpha and you’re good to go

Andy Heywood09:05:44

This is a good general reference -


okay, but how do you decide whether you you' d like to run the spec files or not?


I mean, spec goes to production code?

Andy Heywood09:05:08

yeah, absolutely


I haven't find any example of how it is integrated with the code.


what if I'd like to have it only for development?


is it possible?

Andy Heywood09:05:03

it’s just a library to allow declarative specification of data structures - it’s used a lot in testing, but also for validation of incoming data (in my case)

Andy Heywood09:05:11

check out the guide I linked above


@U012XM1CH39 clojure.spec.alpha is a code library for adding assertions to your code. it gets included in your bundle by default


Hello. Just a question regarding cider and shadow-cljs. Is there a way to automatically start my app and directly tell cider-connect-sibling-cljs to use my unique :app alias ? I have my dir-locals.el on this project with the basic settings:

((nil . ((cider-default-cljs-repl . shadow)
         (cider-shadow-cljs-default-options . "app"))))


it might be a good question for #cider . I’m not sure, and I know that thheller doesn’t use Emacs or CIDER


@U4YGF4NGM yeah i supposed it too. but maybe some dev using shadow-cljs have a tip for me.

Andy Heywood15:05:05

I’ve worked around this for now, but just to throw it out there - it looks like shadow (or cljs in general?) doesn’t support - characters in namespaces when referencing namespaced keywords (i.e. when using spec)

Andy Heywood15:05:11

typically my-ns becomes my_ns.cljs , but otherwise is referenced everywhere as e.g. (my-ns/my-fn …)

Andy Heywood15:05:37

but when namespacing keys, :my-ns/mykey doesn’t work, it has to be :my_ns/mykey

Andy Heywood15:05:52

oh sorry - huge omission on my part - this is only an issue when running the node-test target - it works fine in the REPL


@andrew.heywood can you explain what “doesn’t work” means?

Andy Heywood15:05:02

I should have threaded this too, sry - it’s easy enough to work around, but if it’s a legit issue I can submit an actual report with proper repro etc. Just thought I’d see if it was an obvious known issue

Andy Heywood15:05:10

haha sorry, of course

Andy Heywood15:05:27

basically ‘spec not found’:

Andy Heywood15:05:30

I’m trying to upload shots here but something’s crapping out sry

Andy Heywood15:05:04

/.shadow-cljs/builds/test/dev/out/cljs-runtime/cljs/spec/alpha.cljs:71 (throw (js/Error. (str "Unable to resolve spec: " k))))


can you paste the code that causes this error?

Andy Heywood15:05:22

yeah, I’m trying to simplify it down because it’s all slightly sensitive in it’s current form

Andy Heywood15:05:44

ok this is confusing me. when I recreate it with a trivial example it works fine, but it works because now I can reference the ns properly:

Andy Heywood15:05:24

previously, that failed, and I could only reference my spec as :_spec/spec


did you have an improper ns form?

Andy Heywood15:05:23

I switched between the repl and the test runner, and had a server running the whole time, and probably renamed the namespace… maybe some wires got crossed and I hit an edge case

Andy Heywood15:05:32

I don’t think so?


were you using shorthand syntax like ::lambda?

Andy Heywood15:05:17

going back to the original code that I just fixed, and if it re-breaks, I’ll dm it to you

Andy Heywood16:05:10

nope, it’s all working fine now, back in the state that was previously broken. It definitely was broken, but I’m very sure that after renaming the ns, the REPL was only accepting :my_ns/keyword whereas the test runner expected :my-ns/keyword. I was simultaneously running:

shadow-cljs watch :test
shadow-cljs watch :repl
node dist/node/repl.js

Andy Heywood16:05:58

idk. I’m glad it’s not a real issue though 😄


ah so you renamed the namespace. that’s valuable info. not sure what to do with it tho 😛

Andy Heywood16:05:15

yeah, I can’t remember why/when exactly, it was this morning, I’ve been on the REPL all day. But I remember messing with stuff this morning because I thought it was very weird that I had to reference my namespaced keyword with an underscore instead of a dash

Andy Heywood16:05:40

and I’ve been generating from specs all day using an underscore for a ns that has a dash in it. and when I went over to the tests, nothing worked.

Andy Heywood16:05:12

I’ve figured it out (I think)! When referencing a kw, you have to require the ns separately. So it was all red-herrings - what’s actually fixed the problem is requiring the spec’s namepsace in the consuming namespace

Andy Heywood16:05:52


(s/gen :lambda.leads-spec/lead)
will only work if you also require
[lambda.leads-spec :as ls]


yes, you can't gen/reference specs that haven't been loaded yet

☝️ 4

Hello. Should the build-option :print-fn :none with :target :browser result in my not seeing println messages in the browser console? I’ve tried setting this locally is dev mode and there doesn’t seem to be any effect. Somewhat ironically, I was only checking it disabled printing in dev mode so that I can be sure that I’ve got the correct setting to use in my release build. I’m now wondering if it is overridden in dev when the shadow-cljs websocket is in use. Anyway, I’d like to disable printing in prod / release builds… so does anybody know if this option should still work, because it’s not mentioned in the current documentation, but I can see it in the source code?


@scottlowe I’m not sure, but you can test this pretty quickly by doing a release build


if you’ve already got a dev watcher running, in another terminal run:

shadow-cljs release <build>
and do a hard refresh of the page you’re developing in


Heh. I should have done that initially, but we have a complicated setup (don’t ask!). Was being lazy. Have built in release mode now and it doesn’t seem to work.


yeah print-fn can't be disabled because otherwise you always get an exception for anything that prints


well, you can just set (set-print-fn! (fn [x])) in your :init-fn


but something must be set or you get errors


Okay. Thank you very much for the confirmation, Thomas.


is it possible to use :module-hash-name with a :node-script target ? I couldn’t get it to work but was just wondering if this is possible


no. what would be the point? do you want to guess the name of the script you want to execute?


lol no - it’s more of a versioning thing but I realised it’s a bit of a dumb idea I am using the commit hash instead


ah so you renamed the namespace. that’s valuable info. not sure what to do with it tho 😛


Is there anything special I need to do to get clojure.spec.gen.alpha up and running in a CLJS project with shadow? I’ve followed and added org.clojure/test.check to our dependencies, but when I invoke (gen/generate (s/gen int?)) in the repl I get something like a deref error. (`[clojure.spec.gen.alpha :as gen]` & [cljs.spec.alpha :as s])

Andy Heywood16:05:24

top of my head, having just been through this, you need to require clojure.test.check.generators

💯 4
Andy Heywood16:05:58

i.e. require it in that ns, even though you’re not referencing it directly


!!! Thanks @andrew.heywood you just saved my day (actually my evening 😄 )


Requiring clojure.test.check.generators did the trick

Andy Heywood16:05:12

took me a while to find that one. I’ve definitely sunk a couple of wasted hours into cljs/shadow/spec integration this week

Andy Heywood16:05:22

well worth it overall though!


Yes, I added specs to a hughe part of my lib but what gives if it breakes my tests because of my hand build test data 😄 I’m so excited about this right now. Thanks again @andrew.heywood The future is bright 😎


@thheller I’m seeing some strange behaviour with shadow-cljs :dev-http server redirection. I’m using reitit-frontend so I can switch hashtag routing on or off. Looking at localhost:8280/lung and localhost:8280/lung/centre - these URLs both work with internal reitit navigation, but on address bar navigation /lung works but not /lung/centre. Hashtag versions work from the address bar as expected. I’m concluding that the dev servers can only redirect single-level addresses when typed in back to index.html. So /lung gets redirected to /index.html, but /lung/centre doesn’t. It seems strange, because if there were no redirection happening at all, I would expect the /lung address to fail too. The /lung/centre address gives a 404 in the browser.


@grumplet the :dev-http servers NEVER redirect. that functionality does not exist. unless of course you use a custom handler that does that. the built-ins don't

Andy Heywood16:05:12

I’ve figured it out (I think)! When referencing a kw, you have to require the ns separately. So it was all red-herrings - what’s actually fixed the problem is requiring the spec’s namepsace in the consuming namespace


That’s truly strange then. The docs do say they fall back to index.html when a resource is not found.


Section 5.4.5 of he user guide


yes, it will serve that content. it will not redirect.


Got it. Yes that agrees with the behaviour. Thanks!


I just started using shadow-cljs, and trying to get it set up with cursive. I also just started blogging, and wrote a trying to detail the steps - the documentation was super helpful, so thanks to everyone who contributed to that! Take a look at the post if you get a chance - if you're new to shadow-cljs like me, let me know if anything is unclear, or could be improved, if you're an experienced user, let me know if I'm just doing it wrong... 🙂

Wilson Velez15:05:13

hi @ghufran, I followed this guide and it helps me a lot, you can see if you find something useful


I actually came here to ask - everything seems to be compiling fine, and will show up correctly when I refresh, but the 'hot reloading' doesn't seem to be working - I thought it came 'automatically' with shadow-cljs watch :build_name ? I tried using a different browser and incognito mode in case I had a chrome extension that was interfering, but still not working so far. Any pointers on things I should check?


@ghufran for Cursive I recommend running shadow-cljs pom and importing the pom.xml as a project


if you want hot-reload you need to configure a function to call that does the actual re-rendering. see :dev/after-load


I saw that, but wasn't sure if that was because cursive didn't handle deps then, or because there was some other advantage


> Go to and select node_modules > shadow-cljs-jar > bin > shadow-cljs.jar, then click "open"


this is definitely something you shouldn't be doing


saves you the couple first steps


Wow, totally missed that! - the current "beginner guide" link goes to a blog post, might be best to just make that link to this instead!


Are there any known issues with using with-redefs in shadow-cljs test builds?


I have a simple test like this, which raises an exception when the test is run: is not a function


I have a simple test like this, which raises an exception when the test is run: is not a function


The broader context is that I’m trying to use to mock some functions.


Hi all, I'm a long time Clojure dev, but first time venturing into Clojurescript. I am struggling to get a skeleton deps.edn + shadow-cljs project up and running. I hate to dump a bunch of file contents to the channel, but I honestly can't even figure out a thread to pull on. Here is my deps.edn

{:src     ["paths"]
 :deps    {org.clojure/clojurescript {:mvn/version "1.10.758"}
           reagent                   {:mvn/version "1.0.0-alpha2"}}
 :aliases {:shadow-cljs
           {:extra-deps {thheller/shadow-cljs {:mvn/version "2.8.8"}}
            :main-opts  ["-m" "shadow.cljs.devtools.cli"]}}}
and my shadow-cljs.edn
{:deps     true
 :dev-http {8080 "target/"}
 :builds   {:app {:target     :browser
                  :output-dir "target/"
                  :asset-path "."
                  :modules    {:main {:entries app.core}}
                  :devtools   {:after-load app.core/main}}}}
when I call clj -A:shadow-cljs compile app I get the following exception.
Execution error (IllegalArgumentException) at$loading (js_support.clj:1).
No matching field found: getRegisteredGroups for class
If anybody can spot what I am doing wrong, I would greatly appreciate it.


also if you upgrade to shadow-cljs 2.9.8 you will get an error telling you that 😉


Thanks @thheller! So if I am reading this correctly, if looks like: shadow-cljs 2.9.8 is compatible with clojurescript 1.10.758. Changing that allows me to load.


Although the build starts, I get a build failure no output for id: [ "goog/base.js"] Is that still a deps and/or versioning problem?


well your :entries should be [app.core]. dunno why the spec allows a lone symbol there.


Ah forgot to mention that I noticed that and fixed it after getting the versions correct.


The spec did not allow it 🙂


not sure why you are getting that error. can you post the full trace?


I had to go offline for a bit and when I came back i couldn't reproduce the error. I'm up and running now. Thanks a million for your help!


going through clj is fine but a lot slower 😛

👍 4

maybe try adding these exclusions to the clojurescript dep, but full trace would help.



I thought I recall reading in the shadow user guide that you can inline files with some helper. I've been scanning to docs looking for it but can't find it. anyone know what I'm talking about?


i always google it and find it on clojureverse


maybe that's where i saw it


thanks, i appreciate it