Annually-Funded Developers' Update: July/August 2025

By Kathy Davis

Hello Fellow Clojurists! This is the fourth report from the 5 developers receiving Annual Funding in 2025.

Dragan Duric: Apple M Engine Neanderthal, Deep Diamond CPU
Eric Dallo: ECA, clojure-lsp, clojure-lsp-intellij
Michiel Borkent: clj-kondo, babashka, SCI, clj-kondo, scittle, and more…
Oleksandr Yakushev: CIDER, clj-async-profiler, nREPL
Peter Taoussanis: Sente, Truss, Trove, Telemere

Dragan Duric

2025 Annual Funding Report 4. Published September 4, 2025.

My goal with this funding in 2025 is to support Apple silicon (M cpus) in Neanderthal (and other Uncomplicate libraries where that makes sense and where it’s possible).

Having a decent Apple CPU engine for Neanderthal completed in the May-June period, I could continue building on the work on the Deep Diamond CPU engine for Apple hardware that I’ve started.

I had already found out that Apple’s low-level APIs (BNNS) are not very well thought out (as I wrote in the last report), so I expected it to be a not so pleasant march. And it wasn’t. No wonder why large parts of it are already deprecated, in favor of Graph API (which does not replace it’s functionality, but is a completely alternative way of dealing with tensors and Deep Learning).

However, there were no room for quitting, since we need at least a basic tensor functionality, regardless of DNN operations, so we can later potentially integrate the Graph API and other tensor-based libraries. Besides that, the NDArray and Tensor parts of BNNS is not deprecated, so that’s the stuff we have to work with.

I will spare you the gory details, including lots of segfaults and WTFs, but in the end I managed to tame it, and even fit it into the existing deep-diamond/dnnl API, with backward compatibility (not including the convolution and rnn ops which I found not worth trying to tame at this stage).

Then, just at the end of the month, I even managed to tidy up a Apple silicon enabled Deep Diamond release (0.35.2, 0.35.3).

It’s in the Clojars!

I didn’t have time and resources to advertise it wildly right away, and the next day I already started working on the ONNX Runtime integration, so it’s still an Easter egg for the dedicated folks who actually read these reports. :)

I’ve already worked on Neanderthal, and made a release with assorted bugfixes and improvements.

It’s not a glamurous work, working at these lower levels, but I see bright future for Clojure tensors. Cheers!


Eric Dallo

2025 Annual Funding Report 4. Published September 8, 2025.

In these last 2 months I mainly focused on my recently created project, ECA and its related projects, there were so many improvements and new features, the project grown a lot with lots of people using!

eca

ECA (Editor Code Assistant) is a OpenSource, free, standardized server written in Clojure to make any editor have AI features like Cursor, Continue, Claude and others.

0.2.0 - 0.43.1

There were so many releases I can’t just put the whole changelog here hehe, but the main highlights were:

And many more! come to #eca Clojurians channel.

eca-emacs

After testing other tools, improving a lot and receiving positive feedbacks, I believe ECA emacs offers the best Emacs tool for AI development right now, which is great, there are still so many features to add!

eca-emacs (1)

eca-intellij

New editor support! :tada:
Using the same UX from eca-vscode.

eca-intellij

eca-vscode

Multiple improvements, especially extracted the webview to eca-webview so it can be used by eca-intellij as well.

eca-vscode

clojure-lsp

There were mainly improvements in performance regarding clj-kondo bumps and some small fixes. Also now we have a new custom linter clojure-lsp/cyclic-dependencies!

2025.08.15-15.37.37 - 2025.08.25-14.21.46

Michiel Borkent

2025 Annual Funding Report 4. Published September 5, 2025.

In this post I’ll give updates about open source I worked on during July and August 2025.

To see previous OSS updates, go here.

Sponsors

I’d like to thank all the sponsors and contributors that make this work possible. Without you the below projects would not be as mature or wouldn’t exist or be maintained at all! So a sincere thank you to everyone who contributes to the sustainability of these projects.

c:\Users\kathl\Documents\Documents\Clojurists Together\2025 Reports\mayJune lng term 2025\mb-switzerland-2025.jpeg

Current top tier sponsors:

Open the details section for more info about sponsoring.

Sponsor info

If you want to ensure that the projects I work on are sustainably maintained, you can sponsor this work in the following ways. Thank you!

Updates

Although summer hit Europe and I made a train trip to Switzerland for some hiking with my wife, OSS activity continued in the borkiverse. 20 projects saw updates. As usual, babashka, SCI and clj-kondo saw the most activity. image

One of the big things I’m looking forward to is speaking at Clojure Conj 2025. At the risk of sounding a bit pretentious, the title of my talk is “Making Tools Developers Actually Use”. Babashka started as a quirky interpreter “nobody had asked for” but now many Clojure developers don’t want to live without it. Clj-kondo started out as a minimal proof-of-concept linter and now is widely used tool in Clojurian’s every day toolset and available even in Cursive today. In the talk I want to reflect on what makes a tool something developers (like myself) actually want to use. I’m excited about this opportunity and about my first time visiting the Conj (don’t ask me how I got the Clojure Conj cap on the photo above). Given the rest of the schedule, it’s something I wouldn’t want to miss.

For babashka, my main focus has been making it feel even more like regular Clojure. One example is the change in how non-daemon threads are handled. Previously, people had to sometimes add sometimes @(promise) to keep an httpkit server alive. Now babashka behaves like clojure -X in this regard: if you spawn non-daemon threads, the process waits for them. It’s looks like a small change, but it brings consistency with JVM Clojure, something I’m always aiming for more with babashka. If you want the old behavior, you can still use --force-exit. While implementing this I hit an interesting bug with GraalVM and also found out that clojure -X sometimes stalls when using agents. Maybe more on this next time.

Another change that was introduced is that when code is evaluated through load-string or Compiler/load (which is the same thing in bb), vars like *warn-on-reflection* are bound. This fixes a problem with loading code in non-main threads. E.g. @(future (load-string "(set! *warn-on-reflection* true)")) would fail in previous versions of babashka. You might wonder why you would ever want to do this. Well, a similar thing happens when you execute babashka tasks in parallel and that’s where I ran into this problem.

SCI, the interpreter under the hood of babashka and several other projects, got some critical fixes as well. I detected one somewhat embarrasing bug when loading clojure+.hashp in babashka. It had code that looked like:

(def config {})
(let [config {}
      _ (alter-var-root #'config (constantly config))
     ]
  ...)

In the expression (alter-var-root #'config (constantly config)) the var #'config was mistaken for the local config since SCI’s analyzer used a resolve-like function that also resolves locals. This fails horribly. In 6 years of SCI it’s the first time I encountered this bug though. After fixing this problem, I noticed that babashka’s CI acted up. On every commit, babashka CI tests dozens of Clojure libraries by running their test suites. I noticed that specter’s tests were failing. It turned out that one test actually worked prior to fixing the above bug exactly because the SCI analyzer’s resolve returned a node that evaluated to a local value. But there is no way I could just leave that bug in, so I had to make a pull request to specter as well to set this straight. A new specter version was released that works both with older version of babashka and the new version.

One other headscratcher in SCI was on the ClojureScript side of things and had to do with munging. In interop like (.-foo-bar #js {:foo-bar 1}) ClojureScript munges the field name in the interop form to foo_bar but in the object it stays "foo-bar". The munging of this name wasn’t applied in SCI as an oversight. So in SCI (and thus in nbb, joyride, scittle, etc.) the above expression would return 1 whereas in ClojureScript it would return nil. In contrast, (.-foo-bar #js {:foo_bar 1}) would return nil in SCI but 1 in CLJS. Although fixing this could mean a breaking change in SCI-based scripting environments I decided to align it with CLJS anyway, as switching between SCI and CLJS should not introduce these kinds of surprises.

Other improvements in SCI were made in the area of better using type hints on instance method interop.

And then there’s clj-kondo, the linter that is supposed to spark joy ✨, as far as a linter is able to do that in a developer’s life. Two new linters were added, including one that catches suspicious uses of locking. This linter was inspired by a similar rule in splint. Lots of smaller improvements were made like sorting findings and imported files such that they are consistent across multiple runs that use the --parallel option and across operating systems. And as usual bugfixes and preventing false positives.

One happy improvement to scittle is that referencing a library that was introduced by a <script> tag now was made a lot easier. You can find the docs about that here. The tl;dr of this is that when a library registers itself as a global, you can just use that global in :require now: (require '["JSConfetti" :as confetti]).

Of course, none of this happens in isolation. I’m deeply grateful to the community and the sponsors who make this work sustainable: Clojurists Together, Roam Research, Nextjournal, Nubank, and many other companies and individuals. Every bit of support means I can keep refining these tools, fixing edge cases, and thinking about the long-term direction.

Here are updates about the projects/libraries I’ve worked on in the last two months in detail.

Contributions to third party projects:

Other projects

These are (some of the) other projects I’m involved with but little to no activity happened in the past month.

Click for more details
  • quickdoc: Quick and minimal API doc generation for Clojure
  • unused-deps: Find unused deps in a clojure project
  • http-client: babashka’s http-client
  • quickblog: light-weight static blog engine for Clojure and babashka
  • process: Clojure library for shelling out / spawning sub-processes
  • html: Html generation library inspired by squint’s html tag
  • instaparse-bb: Use instaparse from babashka
  • sql pods: babashka pods for SQL databases
  • rewrite-edn: Utility lib on top of
  • rewrite-clj: Rewrite Clojure code and edn
  • tools-deps-native and tools.bbuild: use tools.deps directly from babashka
  • bbin: Install any Babashka script or project with one comman
  • qualify-methods
    • Initial release of experimental tool to rewrite instance calls to use fully qualified methods (Clojure 1.12 only0
  • neil: A CLI to add common aliases and features to deps.edn-based projects.
  • tools: a set of bbin installable scripts
  • babashka.json: babashka JSON library/adapter
  • speculative
  • squint-macros: a couple of macros that stand-in for applied-science/js-interop and promesa to make CLJS projects compatible with squint and/or cherry.
  • grasp: Grep Clojure code using clojure.spec regexes
  • lein-clj-kondo: a leiningen plugin for clj-kondo
  • http-kit: Simple, high-performance event-driven HTTP client+server for Clojure.
  • babashka.nrepl: The nREPL server from babashka as a library, so it can be used from other SCI-based CLIs
  • jet: CLI to transform between JSON, EDN, YAML and Transit using Clojure
  • lein2deps: leiningen to deps.edn converter
  • cljs-showcase: Showcase CLJS libs using SCI
  • babashka.book: Babashka manual
  • pod-babashka-buddy: A pod around buddy core (Cryptographic Api for Clojure).
  • gh-release-artifact: Upload artifacts to Github releases idempotently
  • carve - Remove unused Clojure vars
  • 4ever-clojure - Pure CLJS version of 4clojure, meant to run forever!
  • pod-babashka-lanterna: Interact with clojure-lanterna from babashka
  • joyride: VSCode CLJS scripting and REPL (via SCI)
  • clj2el: transpile Clojure to elisp
  • deflet: make let-expressions REPL-friendly!
  • deps.add-lib: Clojure 1.12’s add-lib feature for leiningen and/or other environments without a specific version of the clojure CLI


Oleksandr Yakushev

2025 Annual Funding Report 4. Published September 6, 2025.

Hello friends! Here’s my update on July-August 2025 Clojurists Together work. It has been a slow summer for me, but I still advanced in several projects under my wing.

clj-async-profiler

I have been progressing towards a major 2.0.0 release for quite some time, and it will be released soon. The release will contain prominent changes, including the complete transition to JFR file format for collected profiles (compatible with Java Flight Recorder), support for continuous profiling, and a new exciting flamegraph type (secret for now!). I’m also making sure that Flamebin will receive the same new features shortly after that.

nREPL

We have just released nREPL 1.4 which supports configuring dynamic var values for the REPL environment and improvements to load-file middleware. There are already futher improvements in the pipeline, so expect a 1.5 coming soon.

CIDER

Together with Bozhidar, we have released CIDER 1.9 back in July, bringing the accumulated features and fixes to stable-version users. In the unstable version, I’ve fixed a couple annoying bugs, namely:

CIDER users will also benefit from the recent and upcoming nREPL improvements.


Peter Taoussanis

2025 Annual Funding Report 4. Published September 2, 2025.

A big thanks to Clojurists Together, Nubank, and other sponsors of my open source work! I realise that it’s a tough time for a lot of folks and businesses lately, and that sponsorships aren’t always easy 🙏

- Peter Taoussanis

Hi folks! 👋 Will try keep today’s update for July and August brief.

Recent work

Sente

(Sente is a realtime web comms library for Clojure/Script)

Sente v1.21.0-RC1 is out now. v1.21 is a big release with improved performance, improved reliability, improved logging (via Trove) and new high-speed binary serialization that supports Clojure’s rich data types.

The binary serialization is still marked as experimental to be safe, though I have it running in production myself. This is a nice improvement, especially for folks with larger payloads and/or with mobile users that might be sensitive to network speed/limits.

To try the new serialization: just give (taoensso.sente.packers.msgpack/get-packer) to your client and server constructor calls. No extra deps needed.

Truss

(Truss is a micro toolkit for Clojure/Script errors)

Truss v2.2.0 is out now with some usability improvements, and a new demo video to show what the library can do. In short: the goal is to help improve the Clojure/Script error experience. Almost all of my Clojure/Script code uses Truss in some way.

The video should be a decent starting point if you’re not familiar with Truss.

Trove and Telemere

Trove is a modern logging facade for Clojure/Script.
Telemere is the successor to Timbre.

Trove v1.0 final and Telemere v1.1.0 are out now with some usability improvements.

How do these libraries relate?

The two share the same map-oriented logging API:

(trove/log!    {:level :info, :id :auth/login, :data {:user-id 1234}, :msg "User logged in!"})
(telemere/log! {:level :info, :id :auth/login, :data {:user-id 1234}, :msg "User logged in!"})

Both support traditional and structured logging:

A data-oriented pipeline can make a huge difference - supporting easier filteringtransformation, and analysis. It’s also usually faster, since you only pay for serialization if/when you need it. In a lot of cases you can avoid serialization altogether if your final target (DB, etc.) supports the relevant types.

So the structured (data-oriented) approach is inherently more flexible, faster, and well suited to the tools and idioms offered by Clojure and ClojureScript.

Other stuff

Other misc releases included:

As usual please see the linked release notes for details.

Upcoming work

Next couple months I expect my focus to include Tempel and likely Carmine, both of which are long overdue for some love :-)

Cheers everyone!