In my project (CLJS/CLJ fullstack app with a lot of .cljc files) I have a macro called cljs-only that only includes its body when in CLJS. Looks like this:
(defmacro cljs-only
"Wraps code that should only be included in ClojureScript builds.
In Clojure, expands to nil. In ClojureScript, expands to the body.
Example:
(cljs (some-frontend-func args))
Instead of:
#?(:cljs (some-frontend-func args))"
[& body]
(if (:ns &env) ;; &env is non-nil in ClojureScript compilation
`(do ~@body)
nil))
It's just a convenience thing, nicer than typing #?(:cljs (some-form)) a million times.
However, this causes clj-kondo to go haywire, because if it sees use of js-specific imports inside the cljs-only macro, it gives me a ton of Unresolved symbol errors.
Is there some way around this? A way to force clj-kondo to treat this macro as .cljs? I don't know a lot about hooks, but maybe they are applicable here?You could do this with hooks indeed :)
Perhaps this macro even works by just copying it to .clj-kondo/your.org/your_app.clj
and hooking it up with :hooks {:macroexpand {..../cljs-only
the newest clj-kondo has :ns in the env for CLJS compat I think so that should work
Is :hooks > :macroexpand the recommended "first choice" for dealing with macros in clj-kondo these days?
Not necessarily. It's the easiest option, but not the most fine-grained option since you can lose location information
Ah, interesting. I may revisit some of the older hooks I have in my OSS projects since some of those hooks are more complex than the macro expansion they are trying to support 🙂
if you went through the trouble of making analyze-call hooks, I would't downgrade them to macroexpand hooks
analyze-call hooks are more reliable since no information is lost
Then there is the choice to throw an exception from your hook or to create a finding. Creating the finding provides better positional resolution of the issue, so folks get those error squiggles in their editors where the issue really is. Recent example I worked on: • config: https://github.com/babashka/fs/blob/v0.5.30/resources/clj-kondo.exports/babashka/fs/config.edn • and hook: https://github.com/babashka/fs/blob/v0.5.30/resources/clj-kondo.exports/babashka/fs/babashka/fs.clj_kondo
Maybe also of interest, that effort was the first time I also included some tests for a hook. https://github.com/babashka/fs/blob/v0.5.30/test/babashka/fs_linter_test.clj This seems like a good idea to me, and I'll likely add tests to other projects where I've created hooks.
Clojurists Together members can vote for long term support again. I announced my plans for 2026 https://blog.michielborkent.nl/thanksgiving-2025.html If you are a member, voting would be much appreciated. Go vote!