In this post I'll give updates about open source I worked on during November and December 2025.
To see previous OSS updates, go here.
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.

Current top tier sponsors:
Open the details section for more info about sponsoring.
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!
Last November I had the honor and pleasure to visit the Clojure Conj 2025. I met a host of wonderful and interesting long-time and new Clojurians, many that I've known online for a long time and now met for the first time. It was especially exciting to finally meet Rich Hickey and talk to him during a meeting about Clojure dialects and Clojure tooling. The talk that I gave there: "Making tools developers actually use" will come online soon.

In 2026 I'm organizing Babashka Conf 2026. It will be an afternoon event (13:00-17:00) hosted in the Forum hall of the beautiful public library of Amsterdam. More information here. Get your ticket via Meetup.com (currently there's a waiting list, but more places will come available once speakers are confirmed). CfP will open mid January. The day after babashka conf, Dutch Clojure Days 2026 will be happening. It's not too late to get your talk proposal in. More info here.
Here are updates about the projects/libraries I've worked on in the last two months in detail.
babashka: native, fast starting Clojure interpreter for scripting.
process to 0.6.25deps.cljjava.security.DigestOutputStreamns should override metadatanextjournal.markdown to 0.7.222edamame to 1.5.37with-meta followed by dissoc on records no longer worksfs to 0.5.30nextjournal.markdown to 0.7.213java.time.temporal.TemporalField (@EvenMoreIrrelevance)1.12.65sci.impl.Reflector was rewritten into Clojuredissoc on record with non-record field should return map instead of record1.5.35core.rrb-vector to 0.2.0ProcessHandle to to native image ProcessInfo to avoid sandbox errorscli to 0.8.67fs to 0.5.29nextjournal.markdown to 0.7.201SCI: Configurable Clojure/Script interpreter suitable for scripting
:refer-global and :require-globalprintln-strlet bodysci.impl.Reflector was rewritten into Clojurejs-in in CLJSarray-seqclj-kondo: static analyzer and linter for Clojure code that sparks joy.
unused-excluded-var to warn on unused vars in :refer-clojure :exclude (@jramosg):destructured-or-always-evaluates to warn on s-expressions in :or defaults in map destructuring (@jramosg)sorted-map-by, sorted-set, and sorted-set-by functions (@jramosg)array and type checking support for the next functions: to-array, alength, aget, aset and aclone (@jramosg):unquote-not-syntax-quoted in leiningen's defprojectdefproject behavior can now be configured using leiningen.core.project/defproject:refer-clojure-exclude-unresolved-var linter to unresolved-excluded-var for consistencyredundant-let-binding, defaults to :off (@tomdl89):unquote-not-syntax-quoted to warn on ~ and ~@ usage outside syntax-quote (`) (@jramosg):refer-clojure-exclude-unresolved-var to warn on non-existing vars in :refer-clojure :exclude (@jramosg)& syntax errors in let bindings and lint for trailing & (@tomdl89)duplicate-key-in-assoc changed to duplicate-key-args, and now lints dissoc, assoc! and dissoc! too (@tomdl89)babashka/fs:duplicate-require in require + :reload / :reload-all:redundant-fn-wrapper in case of inlined function:unexpected-recur when recur is used inside clojure.core.match/match (@jramosg)repeatedly (@jramosg):ratio type support for numerator and denominator functions (@jramosg)ex-info may be nil since clojure 1.12:refer-global and :require-global ns options in CLJS.cljc filesedamame: configurable EDN and Clojure parser with location metadata and more Edamame: configurable EDN and Clojure parser with location metadata and more
:edamame/read-cond-splicing when not splicing:read-cond function to override :edamame/read-cond-splicing value:read-cond with a function should be spliced. This behavior differs from :read-cond + :preserve which always returns a reader conditional object which cannot be spliced.:features option to just select the first feature that occurssquint: CLJS syntax to JS compiler
"node:fs", etc. to read config files for conditional compilationlet over defn to capture values.js-yield and js-yield* in expression positionsome? as macrovolatile!, vswap!, vreset!pr-str, prn etc now print EDN (with the idea that you can paste it back into your program)#js/Map reader that reads a JavaScript Map from a Clojure map (maps are printed like this with pr-str too)mapvdoseq can't be used in expression contextalength as macroreagami: A minimal zero-deps Reagent-like for Squint and CLJS
innerHTML as a property rather than an attribute:default-value in input range:on-render:on-render hook for mounting/updating/unmounting third part JS componentsNEW: parmezan: fixes unbalanced or unexpected parens or other delimiters in Clojure files
CLI: Turn Clojure functions into CLIs!
clerk: Moldable Live Programming for Clojure
scittle: Execute Clojure(Script) directly from browser script tags via SCI
cherry: Experimental ClojureScript to ES6 module compiler
cherry compile CLI command not receiving file arguments3.3.4extend-type on Objectsatisfies? macro (@willcohen)deps.clj: A faithful port of the clojure CLI bash script to Clojure
quickdoc: Quick and minimal API doc generation for Clojure
quickblog: light-weight static blog engine for Clojure and babashka
:blog-image-alt option being ignored when using CLI (bb quickblog render)nbb: Scripting in Clojure on Node.js using SCI
vim-fireplace infinite loop on nREPL session close.ILookup and Consabs"completions" opneil: A CLI to add common aliases and features to deps.edn-based projects.
fs - File system utility library for Clojure
move never follows symbolic links (@lread)delete-tree now deletes broken symbolic link root (@lread)create-dirs now recognizes sym-linked dirs on JDK 11 (@lread)copy-tree for copying to self too rigidzip now excludes zip-file from zip-file (@lread)root fn which exposes Path getRoot (@lread)copy-tree now fails fast on attempt to copy parent to child (@lread)"" is now (typically) understood to be the current working directory (as per underlying JDK file APIs) (@lread)fs/with-temp-dir clj-kondo linting refinements (@lread)unixify no longer expands into absolute path on Windows (potentially BREAKING)read-all-bytesprocess: Clojure library for shelling out / spawning sub-processes
:discard or ProcessBuilder$Redirect as :out and :err optionsContributions to third party projects:
These are (some of the) other projects I'm involved with but little to no activity happened in the past month.
Published: 2026-01-01
Tagged: clojure oss updates
Dear sponsors,
As we approach Thanksgiving once again, I’m reminded that sustained open source software development, supported by long term sponsors, is not something to take for granted.
I’m genuinely grateful for your ongoing support through GitHub Sponsors. Your contributions make a real difference: my Clojure projects wouldn’t be nearly as polished, maintained, or ambitious without your help.
If you’d like to look back on what happened in open source this past year, you can find an overview here: https://blog.michielborkent.nl/tags/oss-updates.html. The core projects remain clj-kondo, babashka, SCI, scittle, and squint/cherry. Each of them continues to grow in capability and adoption.
I’ve also applied for Clojurists Together again for 2026. If you’re a CT sponsor, a vote in the next long-term funding round would be appreciated.
Here are the main ideas I want to explore in 2026:
I can't make any promises on hard deadlines, but I definitely intend to work toward realizing the above goals.
Aside from software development, I'm also organizing Babashka Conf 2026 the day before Dutch Clojure Days.
As always, feel free to reach out anytime, whether here, on Clojurians Slack, or by email at michielborkent@gmail.com. I love hearing about what you are doing with my projects. Also if you are struggling with something, let me know. Your feedback and use cases continue to shape the direction of my work.
Here’s to another strong year of Clojure OSS!
Thank you for making this journey possible.
With appreciation,
Michiel Borkent / @borkdude

PS: if you aren't sponsoring, but are interested, here are the main ways to do so:
Published: 2025-11-26
Tagged: sponsors
In this post I'll give updates about open source I worked on during September and October 2025.
To see previous OSS updates, go here.
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.

Current top tier sponsors:
Open the details section for more info about sponsoring.
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!
The summer heat has faded, and autumn is upon us. One big focus for me is preparing my talk for Clojure Conj 2025, titled "Making tools developers actually use". I did a test run of the talk at the Dutch Clojure Meetup. It went a bit too long at 45 minutes, so I have to shrink it almost by half for the Conj. The more I work on the talk the more ideas come up, so it's challenging!

Of course I spent a ton of time on OSS the past two months as well. Some special mentions:
sci.impl.Reflector code, based on clojure.lang.Reflector was ported to Clojure with the purpose that it would then be easier to translate to Clojure CLR.str in ClojureScript (worst case 4x, best case 200x)Here are updates about the projects/libraries I've worked on in the last two months in detail.
babashka: native, fast starting Clojure interpreter for scripting.
.addMethod to clojure.lang.MultiFnclojure.lang.ITransientCollection for instance? checksreify + equals + hashCode on Objectjava.nio.charset.CharsetDecoder, java.nio.charset.CodingErrorAction, java.nio.charset.CharacterCodingException in support of the sfv librarynrepl-server completions and lookup op to be compatible with rebel-readlineclojure.lang.Ref for instance? checksNO_SOURCE_PATH instead of <expr> since this can cause issues on Windows when checking for absolute file pathsjava.security and allowing setting deprecated Cipher suites at runtime. See this commit.SCI: Configurable Clojure/Script interpreter suitable for scripting
edamame: configurable EDN and Clojure parser with location metadata and more
clj-kondo: static analyzer and linter for Clojure code that sparks joy.
duplicate-key-in-assoc, defaults to :warning:equals-nil linter to detect (= nil x) or (= x nil) patterns and suggest (nil? x) instead (@conao3)defparkingop macro in core.async alpha:interface flag to :flags set in :java-class-definitions analysis output to distinguish Java interfaces from classes (@hugoduncan)requiring-resolve etc.def body, no results due to laziness bug:not-empty? to only warn on objects that are already seqs:ns-groups (thanks @severeoverfl0w):self-requiring-namespace level from :off to :warningdbg from data_readers.clj since this breaks when using together with CIDERdestruct syntaxget and get-in (especially to catch swapped arguments to get in threading macros) (@borkdude, @Uthar):inline-def with nested deftestsquint: CLJS syntax to JS compiler
mapvidentical? callsnat-int?, neg-int?, pos-int? (@eNotchy)randnull and undefined in #html#html escape fixassoc calls, e.g. produced with ->auto-transient)=, and, and not= even morenot= on undefined and false should return trueassoc, assoc! and get when object argument can be inferred or is type hinted with ^objectstr using macro that compiles into template strings + ?? '' for null/undefinedtake-last should return nil or empty seq for negative numberskeys and vals should work on js/Mapmap-indexed and keep-indexed lazy= when using it on numbers, strings or keyword literals= to a deep-equals implementation that works on primitives, objects, Arrays, Maps and Setsparse-doubleassoc-in on nil or undefineddissoc on nil or undefined:import-maps support in squint.edn (just literal replacements, prefixes not supported yet)reagami: A minimal zero-deps Reagent-like for Squint and CLJS
clerk: Moldable Live Programming for Clojure
unused-deps: Find unused deps in a clojure project
scittle: Execute Clojure(Script) directly from browser script tags via SCI
(.catch ...) was accidentally munched:start attribute to ordered lists not starting with 1 (@spicyfalafel)cherry: Experimental ClojureScript to ES6 module compiler
=, str, not=:macros option + :refer so you can use unqualified macros using compiler state (see macro-state-test)deps.clj: A faithful port of the clojure CLI bash script to Clojure
pod-babashka-go-sqlite3: A babashka pod for interacting with sqlite3
close-connectionget-connection to cache connectionquickdoc: Quick and minimal API doc generation for Clojure
Contributions to third party projects:
str (4x worst case, 200x best case)munge-str public:ns-groups handling by caching regex creation and usageThese are (some of the) other projects I'm involved with but little to no activity happened in the past month.
Published: 2025-11-02
Tagged: clojure oss updates