ClojureScript 1.12.145 Release Notes
Table of Contents
1. Release Summary
| Field | Value |
|---|---|
| Version | 1.12.145 |
| Date | 2026-05-07 |
| Theme | Async/Await |
| Builds on | 1.12.116 (ES2016) |
| Contributors | Borkent et al. |
2. Primary Feature: ^:async / await
Functions hinted with ^:async emit JavaScript async functions.
await is available as a special form within async functions.
(defn ^:async foo [n] (let [x (await (Promise/resolve 10)) y (let [y (await (Promise/resolve 20))] (inc y)) f (fn [] 20)] (+ n x y (f))))
2.1. Key Semantics
^:asyncis metadata on the function, not the varawaitis a special form, not a function value- Inner
fnwithout^:asynccannot useawait deftestsupports^:asyncfor async test functions- Builds on ES2016 target from 1.12.116
2.2. What This Enables
- Direct use of browser APIs (fetch, IndexedDB, Web Crypto) without callback chains or core.async
- Eliminates dependency on core.async for simple async workflows
- Matches the async model JS developers expect
3. Brain Teaser Analysis
9 teaser candidates identified, 4 implemented. Full analysis in async-brain-teasers.org.
3.1. Top Picks
- Serial vs parallel await in let (T1) –
letforces sequential awaits - await is not a function (T3) –
(map await ps)fails - Test passes by accident (T4) – promise never awaited by runner
- binding lost across await (T5) – dynamic bindings don't survive suspension
3.2. Open Questions
- Does the compiler emit binding-conveyance shims for async fns? (affects T5)
- What error does
awaitinside a non-asyncfnproduce? (T2) - Does
refer-globalinteract withPromiseresolution order? (T9)
4. Context
This release addresses a top community request from the Clojure survey. It eliminates the need for core.async in common browser interop scenarios, which was a frequent pain point for ClojureScript adoption.
The async/await design is compiler-level, not library-level. This means the gotchas are baked into the language semantics rather than being workaround-able via library patches.
