This Month in Automerge: September '26
As always, the community hangs out in the Automerge Discord. Come say hi, and let us know if you’d like something included in next month’s edition!
Automerge
New this month: Automerge v3.5.0 for JavaScript and automerge v0.12.0 for Rust. The Rust stack followed with autosurgeon v0.14.0 and samod v0.15.0, which also adds the ability to bind a transport to an authenticated peer ID.
Authors
Automerge changes can now record an author. Automerge has always tracked actors, which are fresh random ID for each editing session. An actor tells you that two changes came from the same session, but not that they came from the same person. On the other hand, an “author” is some unique identifier which you can use to specify a user account, Keyhive identity, or anything else. Automerge stores it in the first change of each actor, and it survives merging, saving, and loading.
import * as Automerge from "@automerge/automerge"let doc = Automerge.init({ author: "f0cacc1a" })doc = Automerge.change(doc, d => { d.title = "Hello" })Automerge.getAuthors(doc) // ["f0cacc1a"]This was the first half of the work we teased in July. The second half (which builds on authors) will be signatures for provenance and revocation. Once you know who wrote each change, you can stop accepting changes from someone whose access you’ve revoked.
Faster Marks
Thanks to Aran Donohue, get_marks now reads from the mark index instead of scanning the text (#1571). This speeds up reading marks at the end of a 100k-character run of text from 9.05ms to 1.6µs. This is on main now and will ship in the next release.
Fixes & Polish
- Large list insertions no longer fail with “Maximum call stack size exceeded”. The Wasm bindings now apply them in bounded chunks.
applyPatchandapplyPatchesnow handle embedded rich-text blocks, and patches that restore deleted rich text include its marks and blocks.- Vincent Liu added
i32column support to Hexane. Vincent works on Coln, which uses Hexane — it’s great to see contributions coming upstream!
📦 automerge-repo
automerge-repo v2.6.0-alpha.4 and alpha.5 shipped this month:
- Ephemeral messages are more reliable. Alex Warth fixed two ways that presence- and cursor-style messages could quietly stop flowing in one direction through a sync server (#742). The fix came straight out of Livelymerge, which streams a lot of ephemeral traffic (more on that below).
- Tanya Shukla fixed a race where a peer asking for a document could get a “don’t have it” reply before storage had been checked.
- Dmytro Maretskyi stopped the Repo from writing to storage just because it loaded a document (#712).
- Darcy Parker continued the memory work with groundwork for garbage-collecting documents that nobody is using: weak caches, plus test infrastructure that can actually observe collection happening (#736).
🗝️🐝 Keyhive
Keyhive is our access control and encryption layer for Automerge and other CRDTs.
A Much Sturdier BeeKEM
John Mumm improved BeeKEM (Keyhive’s group key agreement) performance and correctlness, especially where peers make membership changes concurrently. None of this changes the API, but it’s exactly the kind of work that turns a research prototype into something you can trust.
Threat Model
Keyhive now has a written threat model and glossary. The threat model sets out who Keyhive defends against, which assets it protects (and which it doesn’t), the trust assumptions, and the known gaps between the design and today’s code. If you’re evaluating Keyhive for your app, it’s the place to start.
🏔️ Subduction
Brooke Zelenka and Alex Good continued work on making Subduction behave well in more complex deployments. Subduction v0.17.x and @automerge/subduction v0.23.0 are out.
Smarter Relays
Subscriptions now propagate only upstream (#298), where “upstream” is who accepted (as opposed to initiated) a connection. This means that a hub like a sync server no longer fans subscriptions out to every client connected to it. A relay in a chain forwards each subscription one hop further up. Whatever a relay learns from upstream, it pushes to its own subscribers. This makes the network behave more efficiently.
Bring Your Own Server
New crate: subduction_hyper accepts Subduction WebSocket connections from any HTTP server built on hyper, with an axum extractor behind a feature flag. If you already have a Rust web server, you can now mount Subduction inside it instead of running a separate listener.
Fixes
- Alex Good fixed a bug where Sedimentree included a fragment’s boundary in the heads it reported, instead of the fragment’s heads. It’s a subtle naming confusion with real consequences!
- Many thanks to Lilith Silver for adding remote heads to the connection builder (#271).
subduction_keyhivenow tracks the latest Keyhive, thanks to John Mumm (#308).
🌱 Around the Ecosystem
Livelymerge Streams Its Hands
Livelymerge (the live programming environment whose heap is an Automerge document) published three more lab notes in September:
- A Morphic Programming Kernel: Dan Ingalls’s tour of the Morphic kernel at the heart of the system.
- Improving the Multi-User Experience: what to do when dragging a shape writes ~120 Automerge ops per second. In short, keep rapidly changing state in an ephemeral object during the gesture, broadcast it with automerge-repo’s ephemeral messages, and commit to the document once at the end. This is useful advice for any Automerge app with drag or resize interactions, and it’s the workload that led to the ephemeral message fixes above.
- Early Experiments with AI Programming: since Livelymerge already supports multiple users, the easiest way to give an LLM agent live access was to make it… another user.
Alex Warth also wrote a short note on effective expressiveness: not what a language can express, but what kinds of problems make you want to reach for it.
Byzantine Eventual Consistency at SRDS
Martin Kleppmann gave the keynote at SRDS 2026 in Rome on September 24: Byzantine Eventual Consistency for Reliable Local-first Software. The question is how collaborative apps without a central server can still converge when some participants are actively malicious, and it uses Automerge as the example of a library that makes this approach efficient in practice. If you’ve ever wondered why Automerge’s change history is a hash graph, this talk is a great answer.
linXiv: Local-First Research Papers
linXiv is a local-first desktop app for researchers. It helps you search arXiv, organize papers into projects, and annotate PDFs, with a graph view to see how it all connects, using Automerge (via autosurgeon) under the hood!
📬 Get in Touch
Are you building something with Automerge? We’d love to hear about it! Drop us a line in the Discord. Knowing how Automerge is used in the wild is how we decide what to build next.
If Automerge is important to your product or organization, consider sponsoring its development: reach out to the team at [email protected].
Until next time 👋
— The Automerge Core Team