State of ClojureScript 2024
2024
Number of responses: 179
Language
Language features usage
In the last year, how often have you used the following language features?
Core libraries usage
In the last year, how often have you used the following core libraries?
How do you handle async code?
- missionary
- js-await in squint
- Reframe, reagent
- cljs-thread (disclosure: John here)
- Never use
- Electric/Missionary
- squint
- Missionary
Missing language features
What language features do you miss in ClojureScript?
- js debugger support better support for REPL-driven development
- Common Lisp
- Nothing
- Maybe built-in tools to destructure JS objects and spread those into new JS objects (like the new UIx feature)
- Ease of use
- longs, actual integers : (
- Fast compilation
- concise map creation + destructuring syntax: const name = "rich"; return { name } and function ({ name }) { ...}
- No support for ES6 modules
JavaScript interop
How happy are you with JavaScript interop syntax?
Many developers find JS interop functional but clunky and non-intuitive, often needing to look up syntax or rely on external libraries like applied-science/js-interop for better ergonomics. Async/await absence forces reliance on promise-handling libraries. Lack of IDE autocompletion and data structure conversions (js->clj, clj->js) are pain points. Advanced compilation issues (e.g., property access breaking, externs) cause frustration, leading some to prefer goog.object/get. While some accept interop as it is, others wish for better syntax, built-in improvements, and TypeScript support.
- Mostly I don't pay attention to the syntax, but I have to look it up every time I need to use it. Not having async/await means I need a library to handle promises and I need to look it's documentation as well.
- no ide-autocomplete, need to change cljs and js data-structures back and forth.
- I think that it gets so much better with applied-science/js-interop. Would be better if this is offered in clojurescript. Especially stuff like spread is not easy to translaten from js code samples.
- I am happy with an occasional js->clj and clj->js, and then staying in clj as much as possible!
- code-completion is not available when js interop
- Would be nice if applied-science/js-interop was part of ClojureScript!
- I get why it is like the way it is, but I prefer the style of applied-science/js-interop.
- I am confused by dots and minuses, and end up using goog.object/get for all property access anyway because otherwise advanced compilation ruins the day for me.
- Would be very happy if I knew how to avoid binaryage/cljs-oops
- I prefer to avoid JavaScript interop to reduce complexity
- Interop syntax is nice in that it’s familiar to what we see in JVM interop. The one drawback I’d say it has it that it will sometimes break when using advanced optimizations. In these cases, I have to use js-invoke and goog instead.
- It works pretty well in my experience - I have no complaints
- Property access/method call issues in optimized builds… real footgun, painful workarounds with goog.object/get :(
- The parts I've used work well
- Very few issues with inference when I forget ^js typehint in some interop (advanced build then doesn't work).
- set! doesn't play well with threading macros etc
- Functional, but looks ugly (maybe it should). Would like dedicated syntax for creating (potentially nested) literals without overhead of js->clj conversion.
- We are using it in a very limited way, and it's fine for that
- If externs could also cease to be a problem, that would be great.
- Perhaps there is better syntax out there, perhaps there exist some cljs-oopses but generally I get stuff done.
- It is what it is, even though I struggle with it often enough. I am not seeing some alternate universe where it would be better (as the question seems to imply…)
- Cannot evaluate because never use.
- I wonder what our interop story for TypeScript code is (cf. Ferdinand Beyer's dots library).
- wish i didnt have to reach for goog.object
- Sometimes I have to remind myself the exact syntax, but it is clear. Work a lot with canvas and graphic contexts and `doto` is my friend.
- ^js annotations are annoying
- I don't demand much. What we have seems to work OK for me.
How happy are you with the current state ClojureScript as a language?
ClojureScript users appreciate its expressiveness, REPL-driven development, and stability, with some even preferring it over Clojure. However, concerns include slow compilation, Google Closure dependency, interop with modern JS/TS, and lack of funding & marketing. Shadow-cljs is widely praised but seen as a single-point dependency. Some worry about ClojureScript’s long-term viability due to limited adoption and ecosystem stagnation.
- cljs totally changed the game for me and allows me to move much faster than other languages. Thank you to everybody who helps maintain the various variants!
- love repl, lisp syntax, macro
- the compiler is slow, mutable, hard to use, tweak and reason about
- I have been waiting for years for streamlined support for creating and publishing npm modules that are implemented with ClojureScript and can be used by either ClojureScript or JS applications. I also would like to use node babashka more broadly but the lack of full protocol/deftype support means there are a lot of important libraries that can't be used via nbb (such as instaparse as one example).
- Missing some better support for newer js primitives such as BigInt
- I'm a bit worried about the dependency on Google Closure.
- With shadow-cljs it is very feasible to leverage the JS ecosystem. Only missing some more-cljs native solutions for state management, something like TanStack Query but better with for our use. And maybe something like react-hook-form.
- I hope that it stays around and can continue to work in the light of new JavaScript changes (lang/frameworks/libs).
- I think it is as close to Clojure as can be expected. I feel I can express myself.
- Main issues are building joint Clojure / ClojureScript projects. I wish there was a simple way to integrate ClojureScript into web app I'm building with CLI tools etc. rather than having to use ShadowJS.
- Having to vet libraries that can and can't run through the Google Closure Compiler is a nightmare. Modern JS seems to have evolved beyond the capabilities of ClojureScript, as a result.
- The development-time. documentation, and hiring market tooling is terrible compared to real Javascript. I'm actively deprecating any Clojurescript code I work on both professionally and personally. Typescript has a much stronger foothold, a stronger community, better tools, and requires less of my life to get basic projects working.
- I love it more than Clojure itself, because it gives me power and flexibility, especially with re-frame, that other languages could also provide in the backend.
- It's a bit heavy, would love something like Hoot (Scheme)
- Never use.
- ClojureScript continues to improve and lives harmoniously with clj/cljc code. I’m excited to see how it improves in the coming years.
- I would like better interop with Js dependencies
- Repl setup could be easier
- To large bundles
- Thanks to ClojureScript, I can make a living with my SaaS. But I'm worried for its future: it doesn't get enough marketing, so it isn't popular, and I'm worried that it will disappear.
- I'm concerned about the deprecation of Google Closure.
- It works great and is extremely close to clj.
- Tooling could be better. REPL-driven development with Cider is much more powerful with just Clojure (many features of Cider just don't work with ClojureScript
- Looks like only JVM hás attention. When JS runs everywhere - like or not.
- Cherry answers so many of CLJS's cons though - for some use-cases, cherry is just an obviously more suitable solution - like with being deps for js projects
- Very happy when Closure compiler is gone someday
- I'm interested to see how Cherry evolves. Closer interop with modern JS seems like a good goal.
- We have been running fullstack Clojurescript for over 5 years and the stability of the language is amazing. I can still start up older projects without issues.
- Not that much happening. I'm worried that it will degrade in a meantime.
- Build could be smaller.
- It feels like an unviable language due to how bad interop is with popular/modern javascript tooling
- stable
- Most apps seem to be mostly JavaScript with a bit of ClojureScript to wite things together. The over-reliance on JavaScript has limited the development of ClojureScript libraries
- Perhaps for the future, keeping up with JS and TS is the main thing? Still, I have managed to avoid the churn of that world for a decade thanks to great solutions!
- A better integration with modern JS build tools would be great (like SquintJS).
- cljs to js part of the compiler is slow and full of gotchas. Hot code reload do not alleviate slow compilation speed on large files. Splitting files is not always an option. This is 2024, we know how to make compilers fast. We lack resources to do so. Without shadow-cljs, working with cljs is so painful it defeats entreprise-size projects. Shadow-cljs is still mostly a one man effort (and what an effort! Thank you Thomas). Just like clojure, cljs needs funding. But where does cljs fits in a typescript and web assembly world?
- great language, development seems stalled, would need new (funded) core team not to die away.
Libraries
What schema libraries do you use?
- c3kit.apron.schema
- zod / JS libs
- spec-tools
- Never use.
- c3kit.apron
- None, but interested in malli
- N/A
core.async
Are you using core.async in ClojureScript?
What libraries do you regularly use?
Building web apps in ClojureScript
How do you build web apps in ClojureScript?
- Replicant
- I am using my own framework for my own projects, and React wrappers otherwise.
- Fulcro
- Zero
- nbb
- cjohansen/replicant
- Often use MUI
- Lamdbas
- Never use.
- Vue JS
- Matrix
- Astro with squint
- Replicant
- https://github.com/cjohansen/dumdom
- replicant
- squint
What React wrapper do you use, if any?
- re-frame
- React interop with hiccada compiler
- re-frame state. Really excited to try Replicant though.
- Vue JS Wrapper
- ReFrame
- squint's built-in JSX support
- Never use.
- nextjs
- Replicant, https://github.com/cjohansen/replicant
- squint jsx
- Replicant
- Replicant, although not really a react wrapper.
How do you render your web apps?
What UI component libraries do you use?
- hand-crafted CSS/HTML
- Monday Vibe designs system and Atlaskit
- Daisy UI
- mantine, daisyui
- mantine
- MVP
- mantine.dev
- day8.re-com
- Never use.
- Blueprint.js
- Bulma.io
- Component Library of platforms we intergrate with
- Re-com
- DaisyUI
- Patternfly
- Mantine, re-com
- generally go with minimalist css classless frameworks (like concrete.css) and then add stuff i need.
- re-com
State management libraries
- xstate aka stately
- N/A
- Custom
- Reagent
- matrix
- Duratom
- An atom with a hash-map
- clojure.core.atom
- Convey
- Never use.
- In house peer to peer sync protocol
- from JS: jotai
- plain Reagent atoms
- kee-frame
- flex
- atoms
- reflet
- orestis/reseda
Client-side routing
- electric router
- Fulcro
- Never use.
- fulcro
- Silk
- N/A
Code-splitting
How do you split bundled code in your projects?
- split by business domain
- Not often though
- shadow-cljs modules
Build tooling
How do you build your ClojureScript projects?
- shadow-cljs with bun (and webpack if there are issues with bun)
- c3kit.scaffold
- Vanilla CLJS for libs
- nbb
- Vite
- Never use.
- lein-cljsbuild
- also squint, scittle (no build), nbb (no build).
- Vite (with squint-cljs)
- squint
What tool do you use to develop UI components in isolation?
- Dedicated page in the application with a component library overview
- i just lay them out in a big page.
- N/A
- Own component/styleguide page
- in-house
- Rolling our own devcards/storybook
- just a „demo“ route that renders a whole lot of components etc. in a browseable way
- in the browser with figwheel
- electric-fiddle (unpublished)
- Built in house
- In house
What data format do you use to communicate between client and server?
- RDR
- GraphQL using Lacinia
- Never use.
- Graphql json
How do you sync data between client and server?
- electric
- N/A
- One query endpoint
- Electric
- Sse
- (websockets and transit, but this is all abstracted away by Electric)
- Pathom3
- re-db
- ajax
- Never use.
- Server Sent Events as well.
- pathom
- Kirasystems/views
- REST and custom GraphQL like implementation based on Datomic pull syntax
- websockets and RethinkDB changefeeds, moving over to polling from FoundationDB
- Electric Clojure
- editscript diff sync, ala https://github.com/johnmn3/todosync/blob/1d2127be1fbe75c73f7f24b13b7774b6025fd96f/src/server/todosync/server.cljs#L70 Similar to InstantDB architecture, somewhat - not sure if they're using diffs, but similar principle I believe.
- In house
Web frameworks
What web frameworks do you use?
- raamwerk, my own
- N/A
- sitefox
- hono.js
- reitit
- custom
- Fulcro
- Ring
- Finn stack: Reitit, Malli, Muuntaja, Sieppari, Jsonista
- Hotplate, internal app generator. Plan to oss in future
- ring, reitit
- Lots of metosin libs
- duct
- httpkit + ring
- Luminus is such a high debt for us
- None of the above, but these seems to suggest backend and therefore Clojure?! There we use Duct/Integrant with Reitit.
- ring, compojure
What platforms are you targeting with ClojureScript?
- Tauri
- Never use.
- custom v8 runtimes like a plugin for Pure Data (music/DSP language). very interested in pocketbase.
Where do you deploy your ClojureScript apps?
- VPS
- own server
- Hetzner
- Custom server
- Self hosted
- Been exploring p2p/web3 too
- Customer's own cloud, my own servers
- to our embedded devices
- Digital Ocean, Linode
- Traditional on-prem infrastructure
- On hosts that are physically located within the organisation.
- github pages
- Linode
- self hosted
- Manually on on-prem server (internal apps)
- Digital Ocean Droplet
- Self-hosted at home
- Monolithic app that is distributed as uberjar
- vps
- VM
- digital ocean vps using piku
- Vps: contabo, ovh
- Local systems.
- Application.garden (personal projects), private Openshift cluster (business projects)
- LAN, or Linode
- Never use.
- vps on linode
- Ubuntu VPS supplied from organization
- Uberjar/docker and just plain vm
- VPS, Hetzner
- Github static deploy
- digitalocean
- OpenStack
- GitHub Pages
- Client's Kubernetes cluster
- github-pages
- self host
- regular old non-cloud actual server
- Play and App Store
- On prem
- Digital Ocean
- Hetzner VPS + Coolify (via docker / docker compose)
- Linux servers
- my own servers
- Although it's web technology, distributed as an Uberjar to run server on user's machine.
- Private cloud
How happy are you with the current state of frontend frameworks in ClojureScript?
Opinions are mixed. Some appreciate new tooling (e.g., from Borkdude) and frameworks like Replicant and Electric, which offer fresh approaches. Reagent and re-frame remain stable and reliable, but concerns exist about their compatibility with modern React. Some find Fulcro too complex, while others see ClojureScript as overly React-centric. There’s worry about Rum’s maintenance, and many note that ClojureScript frontends are losing traction in favor of TypeScript. Some prefer sticking with simple, long-lasting solutions, while others are excited about moving beyond React. State management remains a challenge, and some feel frameworks are overcomplicated.
- new tooling, especially from borkdude, is making things really lean and fast.
- I don’t know enough about cljs frameworks to have an opinion
- Bit of a painful transition with the React community investing all its effort and innovation in an approach (functional components and hooks) that the prevalent Cljs libs have yet to fully embrace. Exciting to see UIx and Helix, but doesn't seem ideal to have two such similar libraries competing.
- I don't use frameworks.
- it feels like Clojurescript is dwindling in popularity. Most shops, even heavily Clojure-based ones are not using Clojurescript and that is very sad.
- There's plenty of variety and some really good, stable, mature options.
- Replicant is exactly as simple as I could hope for
- replicant is awesome!
- State management is an open problem. Re-frame depens on reagent which has problems with new React versions. Global state is nice but not every component state needs to be stored globally, and if not careful, depending on top-level keys leads to performance problems without having caching in between, so performance is not obvious. Data sync is also not obvious, with only re-frame, need to take care of caching and fetch observation state by yourself. Having said this, I haven't tried how to do state management with only JS libs like Zustand. Thinking that dilemma is js/cljs data type conversions, if JS would have interfaces like Java, maybe one could drop in a Clojure map, where a plain JS concrete object is expected.
- Apart from reagent, frameworks tend to geel overcomplicated
- They're a complete mess
- reagent, stable
- ClojureScript is overly React-centric
- Fulcro was promising but failed to address the root causes of why web dev is hard. As a consequence its complexity exploded. I had to maintain and deal with tech debt in fulcro apps, not a pleasant experience at all. And the productivity wasn’t there. Reframe is fine, being simpler is a good thing in some cases. Electric is so different, in a good way. very promising. I can finally focus on the business cases and get the job done. Current tradeoffs are speed and DX, but its a price I’m willing to pay for the productivity boost. And it keeps improving. I keep seeing odd comments about Electric on the clojurian slack: - "it won’t work, we tried something like this already", - "it can’t work, science says so", - "I don’t get it... is this corba?" I get that people are busy. But this is not worthy of this community. Pay a little bit of attention, there’s something there.
- As a happy user of Reagent, I see people turning to other frameworks to chase JS wonders. I don't need absolute performance. I'd rather have a really long lifetime of the solution. My project has been going on for 8 years and I haven't needed to change much. There is no valid business reason to change. I have experiment with the options but none of them is a clear winner yet. But keeping up with the JS churn is a must for some other projects.
- Unhappy with reagent/re-frame
- RE-frame is great. UIX is good.
- Never use.
- Love to make apps with CLJS, hate that even Typescript will make codebases more approachable due to „types“
- electric clojure is coming along nicely
- Cljs react wrappers have little value prop over native React, and many growth stage cos which started with cljs circa 2016 have migrated to typescript frontend. You should ask this question on the survey!
- shadow-cljs blows the default react-native "fast refresh" out of the water! -- the default react-native "fast refresh" should be called "Tortoise refresh."
- Mostly happy, but there is a code duplication issue that happens with very large codebases which I outline in the readme of a solution that pulls in some inheritance features and unclosed-functions from OOP (https://github.com/johnmn3/ti-yong)
- Very excited about Portfolio and Replicant. One of next year's goal is to leave the world of React behind.
- Not using any frontend frameworks, so I am super happy with them!
- I am increasingly worried that Rum will stop being maintained. In the chase after the new shiny, there is too much abandoning of working solutions.
- Replicant is the future
- Electric is amazing. I'd also like to shout out the new Caveman which is great as an educational resource.
- Creating React stuff still feels a bit rough around the edges.
- re-frame and reagent are still pretty good.
- long live reagent - the other frameworks that throw away hiccup and a data-oriented style are losing more than they think
- Not big on frameworks
Styling
How do you write CSS?
- Radiance. Replicant has some bells and whistles for easy element animations I'm looking forward to exploring.
- Stylefy
- css-in-js
- Building my own, inspired by emotionJS and cljss
- Mostly UI libs like Material-UI which also handle per element styles
- PostCSS for nesting
- Never use.
- fulcro-css
- Spade
- stylefy
- Classless CSS librarys
- spade
How happy are you with the current state of styling web apps in ClojureScript?
Opinions on styling in ClojureScript vary widely. Some developers are satisfied with plain CSS, while others prefer Tailwind for its speed and simplicity. Several respondents wish for a Clojure-native styling solution but haven't found a solid alternative. CSS Modules support is a common request. Garden is well-liked but could benefit from more active maintenance. Some find styling in CLJS unnecessary, while others struggle with React-based styling tools. Overall many want a simpler yet powerful solution.
- I take responsibility for this
- I have often been using Tailwind. I would like to replace it with a pure Clojure solution, but haven't found one.
- N/A
- Something like css modules is still missing in clojurescript.
- Never understood why people need more than CSS
- Garden could need some help maintaining. Not that I have found anything that needs fixing, but seeing it more actively supported would be nice. I know that the author is still around, but he has limited bandwidth, so would be nice if someone steps up. It is a totally awesome library!
- css is all I need.
- Got used to using Tailwind and now it’s all I need.
- Using React and things like Storybook still feels rough around the edges.
- I don't think CLJS has any business in this
- Tailwind + fast hot reload meets my needs perfectly
- CSS has always been good enough for me and i don't really understand overcomplicating it (though obviously different people have different tradeoffs)
- My favorite way of styling apps is CSS modules and would love something like this in CLJS
- Never use.
- As happy/unhappy as I am with styling in other ecosystems. CSS is kinda like SQL, clearly powerful and very frustrating at the same time
- More automatic/easy element automations would be nice. Replicant apparently has some of this.
- Very hard to compare the actual layouts when changing - intractable bootstrap Migrations comes to mind
- I am not familiar with the recent options.
- I use Semantic UI and it hasn't been maintained in a while. I have no good solution: there is no other mature feature-complete library of styled components that I could switch to.
- I can make it work - CSS / Styling is not my strong suit, but it works.
- It'd be great if CLJS could support all css attributes in inline styling, so we can write more data-driven css attributes, when using other libs we lose the auto completion etc.
- I can do a lot with plain CSS, vars and the modern CSS features.
- I'm less fluent in styling, so something like MUI helps, but I would like to try out a macro bases css library like cljss or uix.css
- Garden keeps things familiar with the hiccup/scss syntax. Being able to write macros and functions for my style builds has also been great.
- It's just CSS- I can avoid the Clojurescript layer entirely
- I'd like something better. But also not complicated.
Testing
What are the proportions of different types of tests in your projects?
What testing libraries and test runners do you use?
- We have no tests
- eftest
- etaoin
- N/A -- I'm bad
- We use the Reflect service. Does that use Playwright undernearh? It would/should be cljs.test, but in practice so far visual inspection works well enough in our situation (which I don’t really trust at all myself; even so, not getting many bugs in production though).
- Tests are run with clojure.test and cljc-files
- Modern Web Test Runner
- rcf
- Never use.
- Reflect
- RCF, Ghost Inspector
- Speclj
- shadow-cljs
- speclj and c3kit.scaffold
- shadow-cljs test
- speclj.core
- shadow-cljs test runner
How happy are you with the current state of testing tools in ClojureScript?
Struggle with setup complexity and lack of clear guidance. Karma deprecation is a concern, and UI testing remains challenging, with a preference for E2E tests over unit tests. Some wish for better debugging tools (e.g., for Emacs), and others rely on Clojure/cljc testing instead of CLJS-specific tools. There's interest in Playwright adoption, but no single testing tool dominates the ecosystem.
- It’s all right
- Can be annoying to set up
- I dont understand it
- We need to start doing CLJS testing.
- Not testing at the moment
- Karma is being deprecated and still indicated as the way to go with ci tests in cljs
- I don't do any ClojureScript testing and I wouldn't even know how. I test cljc code using Clojure.
- I haven’t used many of the other testing libraries, but I don’t think I’ve been able to test my UI code quite as thoroughly in any other js flavor as I can in ClojureScript. The only problem I’d say I’m facing here is that there are some aspects that make testing against an advanced build more challenging, but nothing that’s a showstopper.
- Never use.
- It definitely takes some setting up while our frontend functions are rarely interesting enough to warrant the investment. (We don’t want to have brittle tests that break as soon as some styling is tweaked).
- Much of the goodness from the mainstream JS ecosystem is well represented.
- I'd like to see uptake with Playwright. The issue might be more on having scaffolding in place to run tests, rather than testing itself. It is a balance to invest in automated tests, clicking through the UI helps also in feedback. Unit tests work for Clojure code, usually the Clojure parts run in cljc, so can even be tested on JVM.
- There is no one tool to rule them all. Testing UIs is difficult anyway.
- shadow-cljs is awesome as described above -- it works, and I do not run into too many problems.
- Wish there was a debugger for Emacs like Cider
- I have preferred writing E2E tests over CLJS unit tests for the last three years.
- Haven't done a deep dive here yet - still bootstrapping
Other
REPL usage
Are you using REPL when developing ClojureScript apps?
- Never use.
- Only with backend - but I'd like to change that. Getting a frontend REPL running required a bit more work.
Externs
Do you know what externs are?
How do you divide your time between ClojureScript and JavaScript?
What proportion of the code you produce is AI-generated?
ClojureScript pain points
What are the biggest pain points you have with ClojureScript?
The biggest frustrations with ClojureScript include slow compilation, difficult debugging (especially in production), and poor tooling support. Abandoned libraries and poor JS/TS ecosystem integration being major concerns. The React dependency creates friction, and build tooling (e.g., shadow-cljs, externs, ES modules) is seen as complex and hard to configure. Others worry about the viability of ClojureScript in the future, given JS/TS improvements. Better documentation, faster builds, and improved interop with modern JS frameworks are common requests.
- the compiler is slow, mutable, hard to use, tweak and reason about
- Debugging in production
- Clojurescript was a cool idea about a decade ago, and never made it out of beta and into a production-ready language.
- Abandoned libraries
- I think CLJS should take modified version of the coffeescript route. It's just not feasible to replicate dozens of libraries that constantly push the boundaries of what you can do on the frontend. Good interop with the JS (and even TS) ecosystem should be the highest priority IMHO. To me this means a CLJS compiler that emits ES-modules (see squint) while still providing some of the benefits of CLJS (great syntax, REPL, highly expressive).
- my greatest worry is clojurescript doesn't have enough visibility outside the community
- Coexisting with the Javascript/Typescript world.
- lack of good frameworks like re-frame with modern react versions support
- I did have an issue with getting async code to work once.
- Loving low ceremony babashka tooling
- Would like to understand how to use something like Polylith with CLJS code
- Stacktraces
- Not having to write javascript
- learn once. not new framework every week.
- Without React, not sure if state management would be a problem, but with React, there is friction between cljs and js, maybe because js is re-inventing what cljs already had.
- anything in the JS/React ecosystem requires some pretty deep vetting for inclusion
- Property completion on interop. Direct docs integration from external libs. Overall just the feeling that tooling support when dealing with js/typscript libs directly is mwa icw what you get when doing so from js/ts
- Performance meaning build size (as it wasn't separate checkbox).
- I'm struggling to migrate from an old build system which relies on Figwheel and Leiningen. But understanding how to clean up and make a new CLI based build system that compiles CLJS and deploys it into the Uberjar for distribution is a major headache. I've not got it working yet. And it's very hard to find good, simple, up-to-date documentation or tutorials that will just explain how to do all the things I need done.
- Most issues are just my own ignorance. Community and code quality of libs excellent
- Shadow-cljs is a great tool, but the documentation is reeeeally long and problems with JS/TS occur occasionally. Reagent & re-frame was "the" frontend combo for a long time until it wasn't any longer, and due to React changing in unpredictable ways, I'm not sure what to recommend for new projects. debugging is sometimes more difficult than it should due to CLJS wrapper code, even though I think I'm quite seasoned in reading "raw JS". Writing async code seems like a challenge each time, in contrast to JS where it has not been a problem for several years. Lastly, there could be a clojuredocs for cljs?
- Poor quality legacy code in ClojureScript apps
- React dependency
- Wish compilation was faster. Wish there was a debugger in Emacs.
- After 9 years of working with ClojureScript, I still don't have a reliably working REPL, so I have to use the "save the file and get it reloaded automatically" flow, which is inferior. I also never managed to understand how to do code splitting, so I have to ship my app in a single .js file. It doesn't help that the core team speaks in terms of deps.edn only, and I use leiningen+figwheel. Switching is not obvious and some features (like AOT) are not easy to get with deps.edn. Extern management is a big pain point, I could never get the "automated" solutions to work, so I add externs manually, and when I fail at this, I just use goog.object/get.
- As mentioned, advanced optimizations has a couple nuances to it that break things like with-redefs and interop syntax
- There are very little nodejs libraries for clojurescript for server side usage. But we run our own thing which we should open-source.
- None of the above. No pain points, as we (mostly) know how to configure shadow-cljs. But I do believe that starting out from scratch will still be hard!
- I expect introducing ES6 module system.
- Integration of shadow and cljs compiler into webpack and npm ecosystem
- A bit sad that something like shadow-cljs isn‘t the out-of-the-box experience
- Closure name rewriting can be a pain, and I suspect doesn't improve much on zipped bundles. It also doesn't support many modern JS features. ClojureScript's dependence on it is holding it back. Also related: bundles are too interdependent. ES modules are a far better solution. Larger bundle sizes are a small price to pay for cacheability. For example it would be a _huge_ improvement to have a a shared clojure.core module in a CDN, which can be cached and shared between apps, vs having to download a custom tree-shaken version for each app.
- Viability of CLJS in the future. JS/TS have improved somewhat, and major frameworks have chosen solutions that I wish are not forced upon CLJS users. Will I be able to compete with CLJS in the future?
- Compared to Clojure (JVM) there seems far to few ClojureScript libraries
- shadow-cljs is an incredible leap forward, but trying to play with the JS ecosystem's bundlers, and modues, and Typescript projects, and css includes is frequently painful. Starting a JS project is often as simple as deploying a template, copying and pasting some stuff on the web, and running `npm run dev`. Starting a cljs project is never so straightforward (unless your project doesn't interact with the broader JS ecosystem, which is rare for me.)
- - build tooling: hard to learn, but it looks like building is always complex in many languages - debugging: still using print to debug for most cases...
- Official documentation is lacking
- Bundle size is big. The number of companies using cljs was much larger.
- Messing up externs.
- As the codebase increases in size, not having stronger typing and static guarantees is painful
- Not specific to ClojureScript, but anything targeting JS. The browser environment is very diverse, and we've been hit with a lot of bugs in browsers (mostly Safari on iOS, but also in specific versions of Chrome). Mostly with service workers and storage like IndexedDB (which you would think was stable, as it's a 2011 standard, but iOS broke this completely in some refactoring work a couple of years ago. A separate SQLite process was started, and then got killed by the process manager to recover memory from background processes).
- I've been pretty exclusively using promesa for async and it's much easier to use and reason about than core.async
- dev tooling, lsp is great but can be better
- All of these apply to Clojure equally. The language is great, but we have too many choices for libraries and architectures, and not much guidance. Also docs are often sparse & lack a quickstart
Retention
Has your organization, or have you personally, stopped using ClojureScript in the past year?
Key reasons for discontinuing its use include concerns over difficulty in hiring and onboarding developers, and management's preference for more mainstream languages like TypeScript. Some users also cited challenges with JavaScript interop and complexity, as well as client or organizational pressure to switch to more widely adopted technologies. However, many respondents praised ClojureScript's developer experience (DevX) and functional programming strengths, though they acknowledged that plain JavaScript/TypeScript is catching up in terms of features and ecosystem support. A few mentioned using ClojureScript primarily for small personal projects or expressed concerns about its niche status and perceived complexity.
- Management feels insecure about using such a niche language.
- I stopped using Clojurescript. The bundle size is too big and it just can't compete with modern JS on 'normal web apps'.
- Nowadays I use Clojure(Script) for small personal projects only.
- We do create new projects with ClojureScript, but it is hard to sell ClojureScript into new projects that expect a large development team to be grown. I have a general worry of generalists being outfavored by division to frontend/backend, but I do acknowledge the speed in having focus.
- The DevX of ClojureScript is unsurpassed by anything ive used yet... but plain JS is catching up. ES modules, records, etc. Clojure collections and ops are still on the money though, other attempts keep getting it wrong.
- High performance trading tool migrated to typescript
- Consider squint, svelte…
- We switched to TypeScript due to difficult learning curve for new developers.
- Start to move to TS and NextJS, “more easy to hire and onboard” they say.
- Most of our projects are for customers who force us to use something else - a sorry state of affairs
- Real Javascript is much easier to write, to find documentation for, to find working libraries that are maintained and supported, to find other developers who use (let alone who have heard of) the language, and doesn't require me to DIY a million things to print Hello, World in chrome
- In the process of adopting it
- Most companies I have worked for give up on ClojurrScript as its seen as too complicated. The complexity is always coming from JavaScript packages and interop.
- Is this a good question? Isn’t there a survivor bias here?
- Management decided to use external consultants to rebuild ClojureScript app in more mainstream language.
- client had a bad experience with overbuilding and blamed CLJS
- I have noticed other people are not so interested anymore, and I understand the shiny object is elsewhere in JS/TS/Rust etc.
What resources do you use to learn ClojureScript?
- Github repository examples
- Documentation
- Github Repos
- Can't remember. Most likely all of the above.
- ChatGPT
- AI questions/tutoring.
- Random GitHub etc. pages
- clojure-doc.org
- LLMs
- Colleagues
- just write & read sourcecode
How would you rate your frontend development skills?
Is there anything in frontend/ClojureScript space you plan to learn in the next year?
Overall, the focus is on refining workflows, adopting modern tools, and building more maintainable and efficient frontend stacks.
- UI testing,
- Tonnes. Electric v3, Missionary, web app architecture/libraries/build-tools (checking out starter projects for caveman, kit and biff), Browser APIs for audio / canvas / maybe 3d and AR... uhh probably more!
- I probably won't have the time for a lot of learning — I have a business to run…
- Electric
- server side streaming react components and hydrating it on front end
- want to be more focused on front-end stuff and get better at it
- I hope to get better at delivery in general, and design / aesthetics in particular. I would like to investigate ReactNative
- Replicant, datascript, lots more
- Libraries for time, check out new front-end frameworks
- Squint, svelte.
- How to do everything without JavaSccript or at least minimise JS use and complexity
- core.async, missionary, electric clojure
- How to deprecate it faster
- I don't plan my learning out in advance.
- Using reframe and datascript with helix or rum instead of reagent
- I want to take a better look at Squint.
- update our company tooling to so code splitting
- electric v3, ssr, lsp<->typescript integration,
- I got lib idea in my head I plan to release after holidays. It is state management library that plays well with REPL-driven development. It's gonna be my first lib so I plan to learn how to maintain open-source project well
- Support for cljs in browser script tags
- Es Modules, better way to do treeshaking, performance focus.
- I'm starting a new job where they use Replicant, so I'll be moving away from Re-frame.
- Replicant. Cherry/squint. Stretchgoal: memory management / allocation / GC for data living in SABs.
- Electric Clojure
- Replicant and Portfolio. Finally get core.async after Timothy Baldridges udemy course. It might help solve a few problems on the he UI.
- read missionary(and its dependences) source
- leverage more of the borkverse
- Would like to try to targeting Tauri
- Bundling a library (never done before) that can be a good citizen in the JavaScript/TypeScript world, although I might end up rewriting this particular piece of code in TypeScript after all (also a first for me).
- Uix2 maybe since it seems Reagent won't support newer React features.
- Fine grained process control
- scittle
- No.
- Consider switching from Reagent to UIx, and making use of state management tools in JS/TS space (e.g. Jotai). I want to create a "ready to rock" frontend stack for myself that I understand well, so I can start new projects with good understanding of architecture and maintenance.
- Extensive interop to leverage CodeMirror and other JS-based app building blocks.
- More core.async
- More sci tools
- I'd like to use Uix more and try out uix.css. Possibly try out Helix too for comparison.
- Tests, react native
- Lot of small things and new/updated libs/frameworks functions. In general I have enough knowledge to do anything, there is no need to learn something new to do the job.
- Plan to get back into 3D-programming at some point next year
- Squint with solidjs, electro clojure, more fulcro
- Nothing planned. Study topics usually come up on an as-needed basis.
- Delve deeper into UIx, Helix, refx. Try to stop hating CSS with Tailwind. Incorporate Playbook.
- Maybe Electron or Fulcro. Integrated backend and frontend.
Did we miss anything?
- Web workers are a huge growth opportunity for CLJS IMO. JS doesn't doesn't have a solution for webworkers that doesn't suck - message passing sucks. We have shared memory now though (Shared Array Buffers). And because we're transpiled, it's a bit easier for us to integrate js's shared memory features into more low-level language features. Bringing CLJ's concurrency benefits into the browser (wrt shared state) seems like an opportunity to further differentiate CLJS's benefits over JS - making parallelism on the web easy, like in Clojure. And it'd help further prove out the benefit of going with persistent datastructures in a run-to-completion runtime like JS. It's not easy though. Green field GC/alloc/etc.
- Scittle as an alternative to fully compiled JavaScript is underrated. So easy to get started with (for learning or for simple ‘apps’). (You didn’t mention Squint either… but haven’t tried nor needed that yet.) And you’re not mentioning
- Borkdude libs and tools such as squint, cherry, nbb
- Squint is promising and probably and I feel it will surpass cljs in the coming year
- We use nbb a lot for scripting.
- squint, nbb, cherry
- Maybe something about alternative compilers (a.o.t. the Google Closure compiler). Thanks for all the work you folks do!
- I think Clojurescript should be compare other Javascript transpiler
- Editors. No question about editors. I wonder if Cljs devs still use e.g., Emacs.
- 1) What editors or IDEs are being used? 2) What size codebases CLJS is being used in? 3) What size teams are using CLJS? 4) How many years of experience in frontend and/or CLJS?
- You should ask about clojurescript dialects like nbb. nbb is used a fair amount at work
- Nope!
- thanks for doing this Roman! — @martinklepsch
- I wish there was better tooling support for full stack clojurescript apps (eg maintain two cljs repl connections, but switch not based on file extension but namespace)
- CLJS dialects like nbb, scittle, squint and cherry
- You should have something about use of Babashka and specifically nbb, the JavaScript / ClojureScript version.
- debugger usage
- Have you abandoned CLJS? Would you choose it again? Over Typescript? What is the value prop over TS in 2025?
- AI/LLMs often work like magic with JS/TS. Not so much with ClojureScript. Not sure there's anything the core team and community can do about it, but it's a bummer.
- Shadow-CLJS does my externs automatically :)
- All the SCI tools. Quite weird.
- Not Cljs, but I think it would be interesting to follow adoption of cherry/squint
- You should include more options answerable to ReactNative developers -- I have used ReactNativeWeb as well.
- The usual suspects on error messages and compilation times were no options. Luckily we had open answers. Otherwise happy to fill in and curious about the results. Thank you and good luck.
- Just wanted to note that the AI question might leave put use cases like converting JS UI examples (like say MUI -> Uix) maybe out, if people feel that they edit the result afterwards. General example conversion would be good in cljs anyway. Maybe editor question could have been there. I feel that in pure JS, autocompletion from libraries might be better in some editors than others. I answered the language from cljs point of view, but many of the features I don't use in cljs, I do use in JVM/Clojure.
- Always risky to answer what we use unhappily. i dont want anyone to give a good experience on luminus, but to help leave it behind
- No, looks good!
- Replicant (https://github.com/cjohansen/replicant/)
- squint