# Automerge: a CRDT library for local-first apps that merge without a server

> Automerge is a Rust core compiled to WebAssembly with a JavaScript wrapper, offering CRDTs, a compact binary format and a sync protocol. It is aimed at developers who want concurrent edits to converge without a coordination server, and it is not a drop-in replacement for a relational database.

**automerge/automerge** — A JSON-like data structure (a CRDT) that can be modified concurrently by different users, and merged again automatically. 

- Repository: https://github.com/automerge/automerge
- Website: https://automerge.org
- Stars: 6,633 · Forks: 272
- Language: JavaScript
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/automerge-automerge

## What Automerge solves for local-first applications

The README frames the goal directly: Automerge exists to support local-first applications the way relational databases support server applications, by handling persistence so that application developers avoid hard distributed computing problems. The stated ambition is to be "PostgreSQL for your local-first app." The concrete problem is concurrent modification of the same JSON-like document by different users, with automatic merge on reconnect. Without a CRDT, that merge is either last-write-wins at the field level or a manual conflict resolution step. Automerge provides several CRDTs rather than one, a compact compression format for them, and a sync protocol for transmitting changes over the network. It is for teams building editors, note tools or any client that must keep working offline and reconcile later. It is not for read-heavy reporting workloads, and the README does not present it as a general database.

## How the Rust core, WASM and JavaScript layers fit together

The repository splits into two implementations that are not independent. The core is Rust, and it is exposed via FFI in JavaScript plus WASM, in C, and, per the README, soon other languages. The JavaScript library lives in ./javascript and uses automerge-wasm internally, presenting what the README calls a more idiomatic JavaScript interface. So the data structures and the merge logic run in Rust compiled to WebAssembly; the JS package is a wrapper. The C bindings live in rust/automerge-c. Two consequences follow. First, the binary format is the interchange point, and the repository publishes a separate binary format spec, which is what you read if you need to understand wire or disk layout. Second, the WASM build is not incidental: the README notes it requires the nightly toolchain and the rust-src component, used by automerge-wasm and the JS package to build std with panic=unwind so panics surface as JS exceptions. That is a deliberate choice to turn a Rust panic into a catchable JavaScript error instead of an aborted instance.

## Installing the JavaScript package and making a first merge

The README states that a stable release of the JavaScript package is available as @automerge/automerge. That is the entry point for application code; you do not build the Rust core yourself unless you are changing it. Install the package with your package manager, then create a document, change it, and apply a change from another copy.

```bash
npm install @automerge/automerge
```

The README does not include a JavaScript usage example in the excerpt available, so the exact call sequence for creating and merging documents should be taken from the JavaScript documentation linked from the README, which it describes as complete with tutorials and an API reference. What can be said from the repository structure is that the JS package wraps automerge-wasm, so the operations you call in JavaScript are routed into the Rust core rather than implemented in JavaScript. If you are building from source instead of consuming the package, the README gives this sequence for macOS, which installs the toolchain, the WASM target and the CI script:

```bash
rustup target add wasm32-unknown-unknown
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
cargo install wasm-bindgen-cli wasm-opt cargo-deny
npm --prefix ./javascript install
./scripts/ci/run
```

If the build cannot find cmocka.h on macOS, the README suggests exporting CPATH=/opt/homebrew/include and LIBRARY_PATH=/opt/homebrew/lib before rerunning ./scripts/ci/run. With Nix installed, the flake exposes the same CI entry points, including nix run .#ci and individual jobs such as nix run .#ci-js-tests.

## Where Automerge is the wrong tool

Two limitations are stated by the project itself. The first is the Rust API. The README says the rust codebase is currently oriented around producing a performant backend for the JavaScript wrapper, and as such the API for Rust code is low level and not well documented; it adds that you will need to be comfortable reading the tests and asking questions to figure out how to use it, and points Rust application developers toward autosurgeon instead. If your plan is to write a Rust service against the core library directly, that is a documented mismatch, not an oversight you can work around by reading harder. The second is scope. Automerge is a library and a sync protocol, not a server product. The README describes persistence mechanisms and a protocol for transmitting changes, which means you still choose where documents are stored and how peers discover each other. There is no query layer, no schema enforcement and no server-side authorisation described in the README. For a workload that is mostly reads with occasional writes, or one where a central authority must approve every change, a CRDT adds merge machinery you will not use.

## Automerge versus Yjs: two different centres of gravity

The most common comparison for Automerge is Yjs, and the difference is architectural rather than cosmetic. Automerge's core is Rust, compiled to WebAssembly and wrapped for JavaScript, with C bindings and a published binary format spec. Yjs is a JavaScript library at its centre, with its own ecosystem of editor bindings. That choice shapes everything downstream: Automerge can be embedded from C or Rust, and its merge logic is shared across language wrappers, while the JavaScript API is a layer over WASM rather than the implementation itself. The trade-off is build complexity. The README lists rust, node, wasm-bindgen-cli, wasm-opt, cargo-deny, the wasm32-unknown-unknown target, and for the C library cmake, cmocka, doxygen and ninja. A pure JavaScript CRDT has a much shorter path from clone to running tests. Automerge 3, per the README, achieved around a 10x reduction in memory usage, which is the kind of gain that matters when documents are held in memory on the client. Pick Automerge when the multi-language core and the binary format are assets; pick a JavaScript-native CRDT when the build chain is the thing you least want to own.

## Maintenance, releases and the cost of upgrading

The repository is not archived, and the last push was on 2026-09-21. The most recent release listed is js/automerge-3.5.0 on 2026-09-16, preceded by 3.4.1 on 2026-08-12 and 3.4.0 on 2026-07-31. The README states that the project is formed of a core Rust implementation exposed via FFI, that Alex and Orion are working full time on maintaining automerge, that other members of Ink & Switch contribute time, and that there are several other maintainers. It also says the project tries to respect semver in general. The upgrade cost is concentrated in the WASM boundary. Because the JavaScript package depends on automerge-wasm, a version bump can change both the JS surface and the compiled core, and the README notes the WASM build needs the nightly toolchain and rust-src for panic=unwind. If you build from source rather than consuming @automerge/automerge, you own that toolchain requirement. The licence is MIT, which is permissive and places few obligations on distribution; the repository ships a LICENSE file at the top level. This is not legal advice, and you should read the licence text and the licences of the Rust dependencies yourself, particularly if you redistribute a compiled WASM binary.

## Conclusion

Adopt Automerge when your application needs offline-capable, concurrently editable JSON-like documents and you can accept the binary format and the sync protocol it ships. Do not adopt it if you need a query language, server-side access control or a stable documented Rust API today, because the README states the Rust API is low level and not well documented. Before committing, verify that the JavaScript package version you install matches the WASM build your bundler produces, and read the binary format spec to confirm the compression trade-offs fit your storage budget.

## FAQ

### What is Automerge?

Automerge is a library providing fast implementations of several CRDTs, a compact compression format for them, and a sync protocol for transmitting changes over the network. Its stated objective is to support local-first applications the way relational databases support server applications.

### How do you use Automerge in JavaScript?

The README states that a stable release of the JavaScript package is available as @automerge/automerge, and that the website hosts JavaScript documentation with tutorials and an API reference. The JavaScript library uses automerge-wasm internally but presents a more idiomatic JavaScript interface.

### How is Automerge different from Git?

Git merges committed snapshots of files and surfaces conflicts for a human to resolve. Automerge operates on a JSON-like data structure that can be modified concurrently and merged again automatically, using CRDTs plus a binary format and sync protocol rather than a commit graph.

### What alternatives to Automerge exist?

Yjs is the natural comparison: it is a JavaScript-centred CRDT library, while Automerge has a Rust core compiled to WebAssembly with a JavaScript wrapper and C bindings. The README also points Rust users toward autosurgeon for building Rust applications on Automerge.

## Sources

- [automerge/automerge on GitHub](https://github.com/automerge/automerge)
- [License: MIT](https://github.com/automerge/automerge/blob/main/LICENSE)
- [Project website](https://automerge.org)
- [README](https://github.com/automerge/automerge/blob/main/README.md)
- [Releases](https://github.com/automerge/automerge/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/automerge-automerge
