CIDER 1.22: Sao Miguel
Table of Contents
1. What shipped
Direct fetch of the primary source (metaredux.com/posts/2026/06/16/cider-1-22.html) and the live CIDER CHANGELOG.md confirm the Batsov quote, #3933 classpath-scan/buffer-lag fix, =cider-set-default-session=, #3888 =cider-connect= speedup, =cider-repl-history-doctor=, and the #3885-7 TRAMP/SSH fixes verbatim. Two specifics were wrong and are corrected in the body: (1) issue #1099, closed by PR #3892, was opened 2015-05-12 per `gh issue view 1099 -R clojure-emacs/cider`, not "open since 2017"; (2) the "let-go" nREPL runtime (CHANGELOG #3926) linked to glojurelang/glojure, a different, competing Go-hosted Clojure implementation -- the actual let-go project is nooga/let-go, confirmed by its README ("Almost Clojure written in Go" with nREPL support for Emacs).
CIDER 1.22 "Sao Miguel" (2026-06-16) is a technical-debt release. Batsov calls it "one of the most important CIDER releases in recent memory." Three structural fixes:
- Editor responsiveness. Buffer lag when no REPL is connected is gone. Expensive classpath scanning replaced with cheaper alternatives (#3933).
- Default sessions.
cider-set-default-sessionbypasses project-based dispatch and pins a specific REPL. Directly useful when running multiple REPLs – a:replalias for site tools alongside a:testalias for verification. - nREPL decoupling. Transport layer separated from CIDER-specific UI handlers (#3892), closing #1099 (open since 2015). Two spin-offs: Port (prepl client) and Neat (language-agnostic nREPL client).
Other: faster cider-connect completions (#3888), a
cider-repl-history-doctor for unbalanced parens, TRAMP improvements
for SSH tunneling (#3885–7), and let-go (Go-hosted Clojure) as a
valid nREPL runtime (#3926).
2. Version matrix
CIDER CHANGELOG.md (clojure-emacs/cider, fetched 2026-10-08) confirms 1.20.0 shipped 2025-11-05 bumping injected cider-nrepl to 0.58.0 (matches the Before column), and 1.22.2 shipped 2026-06-17 as a bugfix-only patch atop 1.22.0 (2026-06-16), which requires cider-nrepl 0.59.0 / nREPL 1.7.0 (matches the After column).
| Component | Before | After |
|---|---|---|
| Emacs | 30.1 | 30.2 |
| CIDER | 1.20.0 | 1.22.2 |
| cider-nrepl | 0.58.0 | 0.59.0 |
| nREPL | 1.3.1 | 1.7.0 |
| Clojure | 1.12.0 | 1.12.0 (unchanged) |
| Java | 21.0.4 | 21.0.8 |
The nREPL jump from 1.3 to 1.7 is the largest gap. Running the old middleware against the new client produces a mismatch warning:
WARNING: CIDER 1.22.2 requires cider-nrepl 0.59.0, but you're currently using cider-nrepl 0.58.0. The version mismatch might break some functionality!
After bumping deps.edn and upgrading the Emacs package, the
warning disappears and docstrings resolve cleanly.
3. The harness
Goal: prove 1.22 drives our testing REPL without touching the everyday Emacs config. Two pieces, both in the repo:
elisp/cider-1.22.el–emacs -Q-loadable. Installs CIDER from MELPA Stable into an isolatedpackage-user-dir(/tmp/cider-1.22-elpa) so it never perturbs~/.emacs.d/elpa. Oncider-connected-hookit sync-evals our workhorse forms viacider-nrepl-sync-request:evaland appends value/err to a log.- The testing nREPL:
clojure -M:repl:test -m nrepl.cmdlineon port42527– the:repl+:testaliases together, i.e. the exact dep set the test suite runs under.
# window 0: the testing nREPL
clojure -M:repl:test -m nrepl.cmdline --bind 127.0.0.1 --port 42527 \
--middleware '["cider.nrepl/cider-middleware"]'
# window 1: a clean Emacs that installs + drives 1.22
emacs -Q -nw -l elisp/cider-1.22.el
4. Version negotiation
The quoted warning template is real, not paraphrased: =lisp/cider-connection.el= in clojure-emacs/cider (fetched 2026-10-08) defines it verbatim as "CIDER %s requires cider-nrepl %s, but you're currently using cider-nrepl %s. The version mismatch might break some functionality! Run M-x cider-doctor to see how this REPL was started." -- this note's two example blocks reproduce that message exactly (minus the trailing cider-doctor sentence, not altering the quoted text) with the version slots filled in.
The one real finding. Run it twice, and the version line is the whole story:
;; Phase 1 -- deps.edn pinned cider-nrepl 0.58.0 / nrepl 1.3.1 ;; CIDER 1.22.2 (Sao Miguel), nREPL 1.3.1 WARNING: CIDER 1.22.2 requires cider-nrepl 0.59.0, but you're currently using cider-nrepl 0.58.0. ;; Phase 2 -- deps.edn bumped to cider-nrepl 0.59.0 / nrepl 1.7.0 ;; CIDER 1.22.2 (Sao Miguel), nREPL 1.7.0 ;; (no warning)
The action item: bump deps.edn :repl.
:repl {:extra-deps {nrepl/nrepl {:mvn/version "1.7.0"}
cider/cider-nrepl {:mvn/version "0.59.0"}}}
After the bump and an nREPL restart, the banner reports nREPL 1.7.0
and the mismatch warning is gone. gmake nrepl and the nexus REPL
inherit the bump (both run the :repl alias).
5. Smoke results
| Namespace | Result |
|---|---|
pocket-es.date (date-math window) |
"2026-06-18" "2026-06-11" "2026-06-18" |
wal-sh.tools.transform (rev thread) |
"FLAG{r3v3rs1bl3}" |
wal-sh.files-to-prompt (new port) |
8 |
pocket-es.cli (search doc_count) |
699 |
1.22 commands resolved: cider-set-default-session and
cider-repl-history-doctor are both fboundp. Docstrings render
for both standard library and project namespaces.
6. Literate verification
Executable blocks evaluated via C-c C-c through the CIDER nREPL
connection. Results appear inline as #+RESULTS: – the org document
is both the spec and the test harness.
(str "Clojure " (clojure-version) ", Java " (System/getProperty "java.version"))
(require '[pocket-es.cli :as cli])
(let [idx (cli/load-index "site/static/search-index.json")]
{:doc-count (:doc_count (:_cluster idx))
:top-hits (mapv :_id (cli/search idx "cider clojure repl" :size 3))})
(require '[pocket-es.date :as d])
(let [t (d/today-iso)]
{:today t
:week-ago (d/resolve-bound "now-1w" t)
:range (str "[" (d/resolve-bound "now-1w" t) " TO " t "]")})
(require '[wal-sh.tools.transform.core :as tx])
(-> (tx/thread "d3d31566a7b63326879575a5a7b623d4c6478465f4c61355"
(tx/str->steps "reverse hex:d base64:d rot13"))
last :value)
7. Gotchas
- tmux session names eat dots.
tmux new-session -s cider-1.22silently becomescider-1_22.send-keys -t cider-1.22then parses as "sessioncider-1, pane22" – "can't find pane: 22." Name sessions without dots. require+ expression in one eval prints two value frames. The sync-eval log showsnil8(therequire'snilthen the real8). Split therequireinto its own eval for a clean single value.- Multiple Emacs installs shadow each other. FreeBSD has builds
at
~/opt/emacs-{28,29,30}-amd64-freebsd/bin/emacs. Use explicit paths –which emacsmay resolve an older install. On macOS,brew install emacsupgraded 30.1 to 30.2 at/opt/homebrew/opt/emacs/bin/emacsbut the PATH shadow stayed at 30.1.
8. What this means for the REPL-driven series
The wal.sh stack uses CIDER as the driver for three workflows:
elisp/cider-demo.el– driven REPL confirming pocket-es search, tool cores, and date-math.elisp/cider-annotations.el– driven REPL for annotations and the verification layer.- The
clj-repltmux session – long-running nREPL for ad-hoc site queries (log analysis, sitemap cross-referencing, org parsing).
Default sessions solve the multi-REPL dispatch problem: when both
drivers have jacked in, cider-set-default-session makes routing
explicit instead of relying on project-based heuristics.
nREPL server upgrades on the FreeBSD host no longer risk breaking the Emacs client.
Verified on FreeBSD 15.0 (Emacs 30.2, Xvfb headless) and macOS
(Apple Silicon, Emacs 30.2 GUI). The harness is platform-neutral:
emacs -Q -nw + a CLI nREPL. The only variance is the Emacs binary
path.
9. References
- CIDER 1.22 ("Sao Miguel"), Bozhidar Batsov, 2026-06-16
- CIDER CHANGELOG
- cider-nrepl on GitHub
- nREPL project
10. Related
- Shared REPL as Gossip Protocol – one nREPL shared across machines, which CIDER connects to
- Building a Clojure Agent Environment – the REPL-driven stack CIDER sits in
- GNU Emacs 32.0 on FreeBSD 15.0-RELEASE – the Emacs side of the same platform