Hey folks. I have a (perhaps) dumb question. Context: I come from writing mostly javascript. Avoiding churn is one of the big reasons that brought me to Clojure — I don't want to spend my life tending to dependabot or finding how was it that a minor version upgrade broke something. I don't think it's the best use of my clients' resources, either. I'd like to build something right, deliver it to my client and be able to pick things up the next year, when they need to add some feature —and just monitor it in the meantime. My question is: to what extent do Clojure and Clojurescript eliminate churn? How do the maintenance and durability of, say, a Pedestal + re-frame app compare to those of one built with a typical framework from the js ecosystem?
Clojure itself has almost no churn. You can run an app last built 5 years ago and it runs. But ClojureScript I can't say. I don't think that the ClojureScript libraries and the ClojureScript core will have churn either, but their underlying JS dependencies or the other JS dependencies might cause churn similar to if you were using JS. That said, my impression is that ClojureScript churn is still reduced compared to JS. That's because the closure compiler polyfills, and the ClojureScript surface makes things a bit more "standard". Maybe I'm wrong though.
I can only speak confidently about client side. It highly depends on the type of projects you are going to work on. If NPM dependencies are minimal, you’ll be good. Otherwise if you’ll be using JS ecosystem extensively, which makes sense since cljs is hosted on JS, you’ll be still subjected to whatever is happening in JS world.
That makes sense. And I've seen there's a push from some Clojurescript users to rely less on NPM and build more reliable alternatives; otherwise we end in the same spot.
I’m curious what are you pain points with JS these days?
Mostly the churn and dependency management. I don't necessarily dislike the language (it's a ball of duct tape I've been using for 20 years, so I have some affection for it). While I haven't written functional JS before I think that now that I've been using Clojure for a little while, there are lessons that would apply nicely over there.
I'd add that "minimal" above is not so much about amount as it is about scope. You can have dozens of NPM deps that don't conflict with each other, have a very small scope, and aren't updated every 5 minutes. That will be fine. You have have a single dependency on something like MUI and yeah, that's just a maintenance time sink all by itself.
Thinking through how to answer you has got me thinking about how exactly to define "churn." I guess for sake of conversation "be able to pick things up next year" is as good a metric as any. Say I release software v1: what can cause churn for my users: • People discover issues that have to be fixed. Security stuff, if they are running an old version they are vulnerable. This is less likely the fewer users I have. • I decide to make a change that breaks my users - just cuz or because I "have to" in order to do something • I unintentionally make a change that breaks my users. This gets more likely the more often I make changes • Any of the above happens in a dependency So Clojure really isn't immune to any of this. The mitigating factors are that clojure programs mostly have one notion for what "data" is, as opposed to the Java world where each aggregate gets its own nominal type + bespoke semantics. Clojurescript is much more vulnerable than Clojure on the JVM just on account of being in the JS world where there is "ecosystem churn." If I were designing something today I would look into the HTMXes of the world and avoid Clojurescript/React, simply because fewer moving parts means fewer parts that you need to think about.
a common form of churn that i’ve seen that i think OP is referring to is the churn where your organization has slapped a dependency checker onto github, called security a done deal, and forced devs to deal with any CVE outstanding for any version in the dep stack, perhaps even regardless of severity level and in a world where spreading out your dependency scope is often the norm (like p-himik refers to), that forces any maintaining dev to deal with a failing quality check just about every time they push something, regardless of how small 🙂
Yeah, I've been looking into HTMX / Datastar. It seems that the strategy is relying as little as possible on the js ecosystem.
I have to say, D* is definitely looking nice. Would definitely try to use it, if possible within the scope of project requirements.
@ebernard you're describing the situation that launched me on this "there has to be a better way!" quest last year.
hah glad you agree, i was just about to delete it because i think i was being more bitter than helpful 🙂
Nah, not bitter; I think it's just the reality of tons of devs out there.
For security stuff I wonder how well Clojure ecosystem is being monitored, smaller/less dynamic ecosystem can also mean poorly analysed dependencies
Which to some extent I guess is mitigated by being a smaller, less attractive attack surface, but it's still a good point.
Objectively, Clojure(script) has a tiny community. From my POV, you won’t overcome the churn point at all. Most libraries are made or maintained by one guy or a very small team. There aren’t many, because there aren’t many Clojure developers, and progress is slow. On top of that, it relies heavily on the JS ecosystem. So ClojureScript should be chosen for its features, not for its maturity or stability. But we love Clojure and I'm grateful to all the library devs who make Clojure usable in the professional world.
There are dependency updates, but because of the culture of "no breaking changes" they're much less annoying to deal with