Fork me on GitHub

How does one inject secrets and other configuration parameters into a clojurescript browser app at build time? Is there a way to have a config.edn file in the local filesystem of the build machine that can be read in or otherwise made available at runtime of the app? I’m using shadow-cljs.


what kind of secrets are you intending?


just password like secrets


that you don't want shared with random people on the internet?


then putting them in a frontend is a non-starter


Well, yeah, I know it wil be in the browser. Its temporary. I just don’t want to check them into git.


Also looking for a what the recommended way is to have config stuff from a file for clojurescript


  (:require [shadow.resource :as rc]))

(def x (rc/inline "./"))


combine this with closure defines you can swap out config. remember anything you put in cljs will be shipped and run on someone else's machine and should not be considered secret


Understood about how not secure it is browser wise. The path is relative to the ns/file its in or the :paths?


i think its doing the standard classpath lookup.


Great thanks!


@grumplet if you look at the #1 problem for ClojureScript users it's using libraries


also shadow-cljs has become immensely popular in a relatively short time because it makes this considerably easier to do


that alone isn't a reason to do it, but it means that's something is missing because you can't do it that easily with ClojureScript itself


whether that means ClojureScript projects will be bloated or not is somewhat besides the point


maybe you're doing something for React Native where the payload is less important etc.


the other thing is that the only other way to do it easily prior to :bundle is community maintained repo - CLJSJS


the maintenance burden is non-trivial - Bower for JS eventually went away because it's really not that sustainable to curate everything


I could go on - but I think you get picture - there are many reasons for and few against


one last point is that :bundle has nothing to do w/ Webpack


sure Webpack can consume it, but many many other tools can also consume this kind of output


bundlers come and go, but I'm pretty confident the Node ecosystem isn't going anywhere


@grumplet but maybe you aren't complaining now that I read your statement more closely 🙂 yes if you want to use crazy libs it will just work


Is the only way to “hydrate” an edn expression in Clojurescript is to import a self-hosted cljs to do an eval? Or is there something I’m missing?


you mean data literals?


Like maps and such with just data


clojure.edn is available


Cool, so I can just require and use it then I presume


also take a look at which provides reader conditionals that provide different functionality based on environment variables or values passed in while reading the edn.


I'm running a clojurescript test using the cljs.test/run-tests command, and it contains the following test:

(deftest individual-field-test []
  (dispatch [:checkout-fields :full-name "Some Name"])

  (testing "individual field"
    (is (= '([:full-name "Some Name"])
           (filter (comp some? val) @checkout-fields)
When running the test, the dispatch doesn't seem to trigger and the assertion fails. However when I individually evaluate the dispatch and check the value of (filter (comp some? val) @checkout-fields), it is equal to '([:full-name "Some Name"]), which is what it should be. Why is the dispatch not being triggered in cljs.test?


@pshar10 is that re-frame? if so, you need macro from


This works, but for convenience I tried creating a macro like so:

(defmacro deftest-sync [name test]
  `(deftest ~name ~(run-test-sync ~test))
But when I do:
(macroexpand '(deftest-sync some-test (is (= 1 1))))
It simply outputs
(deftest-sync some-test (is (= 1 1)))
Which is unexpected. What am I doing wrong?


@dnolen - Definitely not complaining - rather the reverse - sorry if it came over like that - I was simply experimenting and reporting on an awkward lib that had previously proved troublesome and was happy to see that it did just work. So, great work 🙂


I have this following idiom in my code:

(deftest my-test
       (is (= 1 2)) ;; etc.
And it seems like a good idea to create a macro which would replicate this like so:
(deftest-sync my-test
   (is (= 1 2))
And I have tried this:
(defmacro deftest-sync [name test]
  `(deftest ~name ~(run-test-sync ~test))
But on doing in the shadow repl:
(macroexpand '(deftest-sync some-test (is (= 1 1))))
I simply get the result:
(deftest-sync some-test (is (= 1 1)))
But I seem to get the correct result in a clojure repl. Why would this be?


I have an myapp.environment namespace like so in an environment.clj file.

(ns myapp.environment
  (:require  [myapp.config :refer [env]]))

(defmacro myapp-url [] (:myapp-url env))
Then I require this in an events.cljs file like
[myapp.environment :refer-macros [myapp-url]]
I get the error
The required namespace "myapp.environment" is not available, it was required by "myapp/events.cljs".
"myapp/environment.clj" was found on the classpath. Should this be a .cljs file?
when using it like so:
(http/get (str (myapp-url) "/somepath"))
How do I fix this?

Lone Ranger14:04:01

Did you try

(ns myapp.cljs-file
  (:require-macros [myapp.environment :refer [myapp-url]]))
? I think the :refer-macros might only work on a .cljc file , but that's just a WAG

Lone Ranger14:04:09

myapp.config doesn't happen to be cljs, does it? if so, might want to make that .cljc otherwise environment.clj won't be able to import it


Hello , how i can do this await client.connect(); in clojurescript? i am new in clojurescript and javascript

Lone Ranger18:04:57

await is alternative syntax for a promise

Lone Ranger18:04:07

what's the async function you're using it in?

Lone Ranger18:04:53

usually something like

async function(blah) { await derp = something(); return derp }


i want to write this await client.connect(); to Clojurescript


connect is async function

Lone Ranger18:04:59

it would be something like

(let [p (js/Promise. (fn [resolve] (-> (.connect client) (.then #(resolve %))))]
  (-> p (.then (fn [] (comment "your code here")))))


thank you alot 🙂 i have to read many things


you don't need to make it that complex


(-> (.connect client)
    (.then (fn [result-of-connect]
             ;; use result

☝️ 4
👍 4
Lone Ranger18:04:49

agreed but wanted to keep syntax basic ... how would you do it?


to have a simpler syntax you'd need a macro right?

Lone Ranger18:04:25

I don't know if it can get simpler but you could use externally bound resolve/`reject` functions to change the pattern over to something like core.async

Lone Ranger18:04:51

I do that on longer chains of .then where I need to pass scope around

Lone Ranger18:04:13

wouldn't make sense here. I like @thheller’s approach

Lone Ranger18:04:28

I would not consider external resolve more simple though >.<


> @takis_ if you really want async / await syntax you can use core.async


for trivial stuff it's not needed, but if your code is heavily async then this can help

⬆️ 4
Lone Ranger18:04:43

wow I have never seen that before

Lone Ranger18:04:56

I have some really annoying service worker code I need to try that on

Alex Miller (Clojure team)18:04:28

the core.async stuff was just added in the last release

Lone Ranger18:04:31

@alexmiller I didn't know you hung out in #clojurescript ! you're everywhere 😄

Alex Miller (Clojure team)18:04:58

I'm like sauron, except a giant ear

😂 4
Lone Ranger18:04:01

Keeping an eye on the riffraff?

Alex Miller (Clojure team)18:04:30

just here to help

💯 12

is there a way to annotate JS errors so that I can pull stuff out with ex-data?


there isn't

Lone Ranger18:04:29

wonders what other cool cljs stuff came out this release


It will be helpful if the guides when they were added and when they were last modified.

Alex Miller (Clojure team)21:04:20

generally, I'm not sure that it would

Alex Miller (Clojure team)21:04:58

many guides are about things that are not new, and thus their creation date is not relevant

Alex Miller (Clojure team)21:04:22

I update guides on the clojure site literally every week based on issues or whatever, but those changes might just be typos or something

Alex Miller (Clojure team)21:04:18

the approach we more commonly take is to annotate in a guide when it became relevant


I said that in the context of this guide: At a glance it is not clear when it became available. (The promise interop looks really nice!)


The other new guide about target :webpack, it was pretty clear the feature is new.

Alex Miller (Clojure team)21:04:54

I believe the top half of that page is new content but something that has been like that for a while. The bottom half could probably use an annotation about which version of core.async it was added in

Alex Miller (Clojure team)21:04:55

If you'd like, feel free to file an issue on the clojurescript-site or become a contributor and file a pull request


I can send a PR, will do!

Lone Ranger21:04:45

Do changes/additions to documentation constitute a large or small change?

Alex Miller (Clojure team)21:04:28

depends if they are large or small :)

Lone Ranger21:04:45


Alex Miller (Clojure team)21:04:00

the question is really whether you can sufficiently review your change in the github asciidoc view or not

Alex Miller (Clojure team)21:04:44

I would say most changes are "small" and you don't need to actually build and view the site to satisfy yourself

Alex Miller (Clojure team)21:04:15

David and I can both make those style touch-ups if needed too

Lone Ranger21:04:10

just wanted to offer how to do from a tools-deps perspective since that document didn't work for me

Alex Miller (Clojure team)21:04:40

sometimes it's better to start with an issue describing the problem

Alex Miller (Clojure team)21:04:51

and then get feedback before a pr

Lone Ranger21:04:00

works for me 🙂


Hello all, how do I convert this

import { Responsive, WidthProvider } from 'react-grid-layout';

const ResponsiveGridLayout = WidthProvider(Responsive);
to cljs?


(def ResponsiveGridLayout (WidthProvider Responsive)) -> not working

Lone Ranger22:04:42

(def width-provider (reagent/adapt-react-class js/window.ReactGridLayout.WidthProvider))
(def responsive (reagent/adapt-react-class js/window.ReactGridLayout.Responsive))

(defn responsive-grid-layout []
  [width-provider responsive])
something like that


@fabrao it’s not possible to tell you why it’s not working without more information. e.g. what “not working” means



(ResponsiveGridLayout #js {:layouts {:lg {:x 0
                                             :y 0
                                             :w 100
                                             :h 100
                                             :i "1"}}}
                             (d/div {:key "1"} "Fernando"))
Cannot call a class as a function at Object.WidthProvider


you can’t call React Components as functions


yes, I saw it


This is the way I think it works

($ ResponsiveGridLayout {:layouts (into-array [:lg {:x 0
                                                    :y 0
                                                    :w 100
                                                    :h 100
                                                    :i "1"}])}
          (d/div {:key "1"} "Fernando"))


thanks 4 ur help


Does anyone use respo? I myself use reagent because it seemed like an obvious choice when I first started using cljs. Are there any pros and cons for using respo instead of reagent?

Lone Ranger22:04:12

@dnolen this is really slick. My 🎩 off to you and your team. Very elegant solution to this callback hell problem