Annually-Funded Developers' Update: July & August 2026

By Kathy Davis

Hello Fellow Clojurists!

This is the fourth of six reports from the developers who are receiving annual funding for 2026. Thanks to everyone for supporting their work and these important contributions to the Clojure community. Their previous reports can be found here:
January/February 2026
March/April 2026
May/June 2026


Bozhidar Batsov: CIDER 2.0, cider-nREPL,Sayid, Orchard, Drawbridge…
Clojure Camp: Supporting and engaging new Clojurians at Conj
Eric Dallo: ECA, clojure-lsp
Jeaye Wilkerson: Jank optimization, runtime excep., Error pgs, C++, Commons
Michiel Borkent: SCI, clj-kondo,Babashka, squint, Buzz, Choq:Cherry, Cljbang.el, and more

Bozhidar Batsov

2026 Annual Funding Report 3. Published Sept. 10, 2026.

The summer turned out to be just as busy as the spring. CIDER 2.0 finally shipped, and once it was out the door I used the momentum to sweep through pretty much every corner of the nREPL/CIDER ecosystem - some long-neglected projects got proper releases, and the nREPL protocol got a couple of brand new implementations in languages I play on the side from time to time. The highlights:

Below are the details, project by project.

CIDER

CIDER 2.0 (“Terceira”) landed on July 15, right on the schedule I had announced in the preview post. The big themes were covered in the last report (transient menus, inline macro stepping, call-graph browsers, source-based find-references, the tracing and tap buffers, rich content in the REPL), so here’s what changed between the preview and the final release:

CIDER 2.0.1 followed a week later with fixes for the problems early adopters ran into: evaluation in a dependency’s source buffer erroring with “No linked CIDER sessions” (in several variants), cider-enlighten-mode never lighting anything up (a 1.22 regression), the macroexpansion commands refusing to expand let/fn/loop, and load-file potentially freezing Emacs on a huge result.

After that master (the future CIDER 2.1) kept moving at a steady pace. A few of the things that landed there:

One more thing. I shipped “smarter form targeting” on master - the evaluation commands resolving the form from where the cursor actually is, rather than the form before it - wrote about it, got a lot of feedback, and reverted it a few days later. CIDER 2.1 will keep the classic Emacs semantics. Fifteen years in, the existing behaviour is the contract, not an implementation detail I get to tidy up. The detour wasn’t wasted, though: it surfaced a bug where the text of a line comment was treated as code, and the “at point” family of commands is a direct result of it.

cider-nrepl

Three releases in July, wrapping up the tools.deps migration and driving the CIDER 2.0 launch:

Orchard

Orchard 0.44.0 shipped on July 4, mostly thanks to Sashko’s inspector work (a replace command, truncated table columns, ARef contents rendered fully). My part was a round of tests for the less covered namespaces and, later on master, a fix for orchard.print ignoring custom print-method implementations for records and collections. Thanks, Sashko!

clj-refactor 4.0

clj-refactor.el 4.0 is the release I had been promising for a few cycles. It requires Emacs 28.1+ and CIDER 2.0+, and it’s a big one:

I still think the long-term home for the most useful bits is CIDER and clojure-mode, but at least the project is in good shape while that’s being figured out. I’d still love to hear from clj-refactor users on this.

clj-suitable

clj-suitable, the ClojureScript completion backend, was another project that had been coasting for years:

Sayid

The Sayid revival continued at a brisk pace, with five releases between July 1 and July 17:

Drawbridge

Drawbridge is nREPL’s HTTP transport, created by Chas Emerick in 2012 and “technically maintained” ever since. I finally gave it the attention it needed:

nREPL

No release this cycle, but master is shaping up nicely for 1.8:

The nrepl.org site also picked up links to several new clients and servers (Nautilos, nREPL.hx for Helix, Janet and Steel Scheme servers).

nREPL on the BEAM

nrepl-beam is a brand new project I started in July, mostly because I wanted to see how well the nREPL spec holds up when implemented from scratch outside the JVM. It’s home to:

0.1.0 shipped on July 14. Both servers implement the full op set (eval with streamed output, sessions, interrupts, stdin, load-file, completions, lookup) and pass neat’s cross-implementation integration suite alongside Clojure, Babashka and Basilisp. Writing them was a good test of the spec, and it produced a few of the documentation fixes listed above. Turns out the best way to find holes in a spec is to implement it in a language you barely know.

mezcaml

In the same spirit, mezcaml is a minimal nREPL client for OCaml: a small client library plus a command-line REPL, working against any nREPL server regardless of the language on the other end. No release yet, but the core protocol works, it reads whole forms, and it has server-driven completion. Nothing serious - it was a fun way to combine my recent OCaml hacking with nREPL.

clojure-mode, clojure-ts-mode and MrAnderson

Smaller things: the #_ toggle commands in clojure-mode were renamed to clojure-toggle-discard and friends (matching Clojure’s own terminology, old names kept as aliases), both modes got a :to-have-face matcher for font-lock tests, and clojure-ts-mode now checks the indentation of its sources on CI.

MrAnderson 0.7.1 added a command-line interface, so it can be run without Leiningen, and reworked its downstream integration tests against cider-nrepl and refactor-nrepl, which had silently stopped exercising local changes. Oops.

Blog posts

I wrote a lot this summer, mostly a series on the notable changes in CIDER 2.0:

What’s next

CIDER 2.1 is the obvious next milestone, and it’s mostly a matter of letting the clojure-ts-mode integration settle. After that I’d like to cut nREPL 1.8 with the TLS and URL work, and get mezcaml and the BEAM servers to a point where they are genuinely useful to someone other than me.

Thanks to Clojurists Together for the continued support of my Clojure OSS work! You rock!


Clojure Camp

2026 Annual Funding Report 4. Published Sept. 13, 2026.

What happened:

Plans:


Eric Dallo

2026 Annual Funding Report 4. Published Sept. 13, 2026.

Lots of work in July and August! ECA got closer to the editor with inline chats and LSP navigation (clojure-lsp integration :heart:), alongside more work on reliability, chat history and the client experience. On clojure-lsp, I continued addressing edge cases after the huge performance improvements from the last report, with a new refactoring and help from contributors making the project easier to debug. Thanks ClojuristsTogether and everyone helping with feedback, issues and contributions! :heart:

ECA

The main highlight this time is being able to talk to ECA directly from the code, without switching to the chat window! This builds on the same server and protocol used by the existing clients, so inline conversations can reuse chat history, call tools and ask for approvals too. As usual the changelog is huge, so here are the highlights since the last report:

image

0.145.0 - 0.157.3

Also, there were lots of improvements in eca clients repos related to those changes.

The experimental eca-cli also received community contributions for fuzzy file selection, background-job management, MCP status and diff previews before approving edits. Still early, but really nice to see the terminal client moving forward!

clojure-lsp

Following the memory and startup work covered in the last report, these 2 months were about fixing edge cases, adding a new refactoring and improving the contributor experience, still unreleased:

Thanks to blueskyonmars for helping with the debugging and contributor documentation improvements!


Jeaye Wilkerson

2026 Annual Funding Report 4. Published Sept. 11, 2026.

Hello Clojurists Together members! Thank you so much for the sponsorship this year. Here is my update for July and August, which is extracted from my recent blogpost here.

Uncaught runtime exceptions

In today’s modern C++ compilers, there’s no standard, portable way to get a stack trace. Coming from the JVM, this may sound surprising, but it’s par for course in the native world. Even worse, jank is JIT compiling C++ code and we want to get accurate stack traces which include those frames as well. Even worse, we need to map some of that C++ back to actual jank code. So, in order to get beautiful, accurate stack traces for jank’s uncaught runtime exceptions, there was a lot of work to be done. Check out the results!

image

As you can see in the figure above, an exception was thrown from the C++ code backing clojure.core/subs. jank properly reports the error by pointing at the nearest user’s Clojure call, skipping over the one in clojure.core which calls the C++ function. In the stack trace, we can see two Clojure-specific frames, numbered as #1 and #3. First, we see the frame for clojure.core/subs. Then we see the frame for user/foo, which actually does the call to subs. Note that both of these frames include the exact arity that was used, as well as the precise source location in their respective jank files.

What you’re not seeing here is that this stack trace is pulling debug info from three separate places:

The current executable, for all of the non-Clojure frames. An AOT-compiled object file, which was loaded when clojure.core was required. This is equivalent to Clojure JVM’s .class files. A JIT-compiled object file, which was added to the LLVM JIT runtime when the user/foo function was compiled.

After my recent efforts, jank now weaves all of these together seamlessly to provide you a lovely error report. This works reliably on macOS and on Linux.

Error pages

Building on the error output above, you may also notice the URL that’s tucked into the bottom of the code snippet. Since the original error reporting design last year, I have intended for jank to have a dedicated error page for each error. Each page should provide more information about the error, common causes, and suggested fixes. All of these pages have now been created and are part of the jank book. Some of them are more bare-bones than others and I plan to continue filling them in over time. Getting them created sooner will start aiding in SEO, though, which will help ensure that if you search for any jank errors you hit, the right resources will be shown to you.

Here’s an example of what I have in mind:
analyze/invalid-cpp-conversion

C++ candidates

I have saved the best for last, as far as error messages go. We know that Clojure is infamous for its error messages and I hope to have shown how jank addresses that. However, C++ is also infamous for its error messages and jank is just as much C++ as it is Clojure. C++ is a much scarier beast when it comes to all of the possible things that can go wrong, though. So how can we reimagine C++ error messages? Well, I gave it my best shot. Take a look. :)

image

The call is ambiguous because the second argument is an int, which directly matches neither long nor short but can implicitly be converted to either of them. jank’s AST is intertwined with Clang’s AST, so we can extract all of the necessary information to render this neatly. Unlike Clang, or GCC, jank renders these in a table format which I find to be incredibly succinct and appealing.

Also, as a bonus, the signature and source information for these bar functions is correct, even when they’re declared inside of a cpp/raw in a jank file. Let’s take a look at another one.

C+ JEaye 2

When there are many candidates to report, jank optimizes useful output by ranking the candidates based on argument count, required conversions, as well as access levels. By default, jank will only show the top three candidates.

Finally, I’ll show one more image, which is of a special kind of ambiguity with some jank-specific behavior. On top of normal C++ overloading, implicit conversions, etc, jank also supports automatic trait conversions, which use a well-known trait to convert to/from jank objects and native values. If an argument to a native function is a jank object, the compiler will consider whether or not a trait conversion can be used. However, this can result in ambiguities, too, if multiple candidates are viable. Here’s an example.

image

There’s a lot more that jank can already do with these C++ candidate failures, but I can only show so much in a blog post. I’m sure you’ll see more next time you’re writing some jank code!

Why bother with all of this?

You may not be as excited as I am about these images of error reports. That’s understandable. It’s partly a compiler nerd thing, since effective error reporting can be quite tricky. However, it’s also partly a huge usability win over not only Clojure JVM, not only Clang and GCC, but also the status quo in a lot of developer tooling. I am trying to build a language, and tooling ecosystem, that is the best it can be. That’s the language I want to use. I want to entice others to try it by dedicating this time to usability, too.

To me, this is incredibly important.

Native build system

Another large system I’ve been working on is jank’s native build system. This is a Cargo-like build system, for those familiar with Rust. The goal of the build system is to enable easy consumption of native libraries, both from the installed system and from compiled sources. The jank build system stands on top of Clojure’s existing package management, namely through Clojars. When you add a dependency, the jank tooling will automatically pick up if that dependency has a native jank build script and will build the package locally. These scripts are always run in a sandbox which has no access to your personal files. This is an improvement over the default Cargo machinery.

This build system was originally created by Kyle Cesare and I’ve been further improving it these past few months by adding sandboxing support to macOS, improving static linking support, and overall making things more robust and stable. Now that we have a powerful native build system, what we need is a repository of high quality packages. That is precisely why I started the jank commons.

jank commons

The jank commons is an official repository of native jank packages published to Clojars. Each of these packages integrates seamlessly into the jank build system and has an example project which is continuously compiled. Following Rust/Cargo’s naming scheme, the jank commons is currently full of foo-sys packages. The -sys suffix conveys that it’s a package which provides a system library without providing a higher level API. Writing a higher level API is left up to other packages which then depend on the -sys packages. The key benefit here is that the higher level packages don’t need to bother with all of the system details of packaging native libs and can just focus on writing good APIs. Another benefit is that generally only -sys packages will need native build scripts, so isolating those can further help with security. Even better, since jank has seamless C++ interop, idiomatic Clojure APIs are optional.

An even easier way to browse the native packages jank has is through the awesome-jank list. This is mainly populated by the jank commons right now, but please take this to be a call to action to get more native libs packaged for jank! The jank commons README has a guide for exactly how to do this and the whole native build system is thoroughly documented in the jank book.

Everything else

There’s a lot more that’s been going on in the jank repos, but it’s too much to cover in detail here. For example:

What’s next

This is the last post before my talk at Clojure Conj 2026. If you can’t make it, check out the free live stream! In the coming weeks, I will be racing to improve jank’s stability, portability, and usability, leading up to the Conj. After the Conj, and for the remainder of the year, I’ll be focused on much of the same.

It’s my goal to get jank into your hands, dear reader. For many of you, I think that jank is already capable enough for you to begin your tinkering. With the addition of the jank commons, starting a new raylib game in jank is as easy as lein run. Getting a distributable binary is as easy as lein compile. What follows is just polishing up all of the rough edges so that developing your games and applications is a breeze.

If you’ve been waiting to try jank, give it a go! If there’s something you need which jank is missing, let me know! I’ll make sure it’s noted down and prioritized.

I’ll see you all at the Conj.


Michiel Borkent

2026 Annual Funding Report 4. Published Sept. 11, 2026.

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

To see previous OSS updates, go here.

Sponsors

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

gratitude

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. If you work for a company that uses my OSS, please ask your employer, that would be even better. Thank you!

Updates

In the past two months it was summertime in Europe. Due to a couple of heatwaves, it was the perfect time to spend inside and enjoy my new air conditioning, while coding ;-).

The first half of July was mostly spent on improving performance and compatibility of SCI on CLJS. SCI now JIT-compiles interpreted function bodies to JavaScript at runtime, which closes a lot of the gap with compiled ClojureScript: a tight numeric loop went from ~175ms to ~7ms, over 20 times faster than the interpreter. Implementing core protocols on custom types now also works. There’s hardly anything you can’t do in SCI that you can do in compiled CLJS. I released new versions of scittle and nbb that take full advantage of this.

Also in the middle of July, clj-kondo got a pretty cool enhancement. It infers types of function arguments from how they are used. E.g. when you write (defn foo [x] (inc x)) we can infer that foo is a function that takes a number. I took this principle as far as I could while preventing false positives. Of course, clj-kondo supports the latest Clojure 1.13 destructuring changes too.

In the second half of July I spent significant time on improving babashka tasks with automatic help and completions, backed by babashka.cli. You can read all about that in this blog post: Babashka tasks with automatic help and completions

In August I had the pleasure of giving a talk about Reagami at Func Prog Sweden. In the talk I gave an interactive demo of how to use Reagami in a Squint project through a REPL. I also went into detail on the algorithm that powers the fast DOM diffing. While preparing for the talk, I added SSR to Reagami too. You can view the talk on YouTube:

The last few weeks of August I created babashka.ffi, a new namespace in babashka to call C libraries. See my previous blog post: Babashka 1.13.220 gets FFI. To validate the design I wrote four libraries with it: babashka.sqlite, babashka.duckdb, babashka.postgres and filewatcher. Each one exercised a different corner of the API, along with some examples based on raylib. PacMan is particularly cool:

pac-man running in babashka through babashka.ffi and raylib

Right now I’m looking forward to giving a babashka workshop at the Clojure/conj together with Rahul Dé. We’re still polishing the workshop material behind the scenes and I’m excited to see how it’s turning out. I’m sure it’ll be a lot of fun and hope to catch many of you there.

In between all of this, I also worked on squint. It now supports the core protocols, so you can plug in your own collections and use them with core functions. E.g. you can use Immutable.js with Squint. I’m thinking about lightweight immutable persistent data structures for squint, but so far I haven’t had much need for them, outside of Advent of Code puzzles.

The above was all about making existing projects better. But I also had a few new creative ideas:

Here are some highlights per project. See each project’s CHANGELOG.md for the full list.

Other projects

These are some other projects I’m involved with, but little to no activity happened in the past two months.

Click for more details