description: How SilverBullet merges concurrent edits from other users, devices, agents and scripts, and what happens when they can't be merged automatically. tags: glossary maturity/experimental references:

  • server-common/src/space/disk.rs
  • server-common/src/space/conditional.rs
  • server-common/src/reconcile.rs
  • client/external_merge.ts
  • client/codemirror/conflict_markers.ts
  • client/codemirror/external_presence.ts
  • client/sync_recovery.ts
  • client/spaces/base_store.ts
  • plugs/index/conflict.ts

A Space can be shared: several people with accounts on the same server, editing the same pages. SilverBullet supports this, but it does so in a very specific way.

One core premise of SilverBullet has always been that your Space is just files on disk, and those files are the source of truth. This commitment extends to who and how those files may be edited. SilverBullet deliberately does not want to be the “owner” of your files: third-party tools (or other people) should also be able to freely edit files.

For instance, you may have other markdown capable editors pointed at the same files (for whatever reason), scripts that append to files while you are editing them, coding agents that make edits, team mates connected to the same space.

SilverBullet will do its best to make this “diversity” of edits work.

However, because of the deliberate choice to embrace all these sources of edits, more “classic” real-time, collaborative editing (like e.g. Google Docs) e.g. via CRDT is tricky. Instead, a combination of active file watching and three-way merging gets us quite far.

This page describes just the editor’s real-time-ish behavior. Other features relevant for the collaboration use case are:

There’s also a guide on working together.

Auto-merging concurrent edits

When two edits land on the same file around the same time, the server reconciles them with a three-way merge (each side’s edit against the last version they agreed on) rather than just letting the last write win.

Merging is line- and word-aware: if you and someone else edit different words in the same line or paragraph, both edits should land cleanly with no conflict. Edits that touch the same words collide — and so, occasionally, can edits that don't, when a slow or flaky connection leaves one side merging against an older version of the page than it has already received.

Propagation is near-realtime: a change made elsewhere typically shows up wherever else the file is open within a couple of seconds.

Conflicts

Sometimes both sides really did change the same words, and there is no sane way to merge them automatically. When that happens, the file is written with Git-style conflict markers. In practice, you never have to read that by hand. The editor Live Previews each conflicted section as an edit conflict widget showing both sides, as well as the original.

Binary conflicts

Images, PDFs and other binaries (and text files over the 1 MB merge limit) can’t be merged, so a genuine conflict instead produces a sibling copy named name.conflicted-<hash>.ext next to the original, where <hash> is a short hash of the losing version’s bytes.

Live external edits and attribution

Changes written to a page you have open are applied to your open editor within moments, as small, cursor-preserving edits rather than a full page reload. They land in the undo history like any other edit, so Cmd/Ctrl-z reverts an external change too. The inserted text is briefly highlighted, fading out after a few seconds. When the server can verify who made the change, the highlight carries a small label with that account’s display name. This attribution is best-effort.

Offline and flaky networks

SilverBullet remains local-first: edits you make offline (or while Sync is struggling with a flaky connection) accumulate locally and reconcile with the server once you’re back online, following the same merge and conflict rules as above. A deletion never silently wins over a concurrent edit — if you edited a page that someone else deleted (or vice versa) while you were offline, the edit survives and the deletion is suppressed, surfaced to you as a notification rather than quietly discarding your work.