opbox
Real-time sync for plaintext files
opbox is an<br>experimental daemon that<br>syncs a directory of plain text files between machines in<br>real time.
It works at the filesystem level (meaning everyone can keep<br>their own editor) and merges concurrent edits with CRDTs<br>instead of conflict copies.
Syncs end-to-end encrypted through a shared log on<br>s2.dev, or self-host it with<br>s2-lite.
See demo video ↓<br>Install it →
Use cases
Share an Obsidian or Logseq vault
The opbox raison d'être basically. Our CRM is just<br>folders of markdown docs, edited in some combination<br>of Obsidian & various plain text editors, plus local<br>agents. And git is too slow for this!
Pair on a repo (between commits)
You can keep using git at meaningful checkpoints,<br>but use opbox to sync edits in between. opbox<br>supports a .opboxignore file, and seeds<br>it from .gitignore when already<br>present.
notes.md — editor
notes.md
zsh — 80×25
Design
Inherently local-first
The files on disk are the core data. The opbox<br>daemon just listens for edits, and maintains shadow<br>CRDT<br>documents.
If you go offline, the daemon<br>can re-sync later when it's able to exchange CRDT<br>ops with the shared log again.
Text files only
Files with non-UTF-8 bytes are ignored, as there's<br>not a reasonable way to convert edits on arbitrary<br>binary docs into CRDT ops.
If you need<br>to sync images, PDFs, or etc., keep using git or<br>another tool for those in combination with opbox.
Editor agnostic-ish
opbox works at the filesystem level, meaning you can<br>edit your text files with any editor you like.
Generally speaking, opbox works best with editors<br>that are configured to autosave frequently.
Tested via simulation
Deterministic simulation tests<br>drive complicated multi-daemon scenarios, and assert<br>on CRDT invariants (i.e. that ops exhibit<br>idempotency, commutativity, associativity), and that<br>workspaces converge on a single materialization.
Walkthrough
How it works
Init or clone an existing opbox workspace into a<br>directory, and start the sync daemon.<br>(cd my-sync-dir && ob init<br>&& ob start)
When running, the opbox daemon listens for<br>native file events within the workspace.
When a text file is saved, the daemon diffs it<br>against a shadow CRDT copy and encodes the<br>change as a new CRDT operation, using<br>yrs, the Rust port of Yjs.
The op is encrypted with the workspace key, then<br>appended to a durable, shared log on<br>S2.
Every other daemon syncing with the workspace<br>reads the op, updates its CRDT documents, and<br>materializes the new state on disk.
machine A S2 log machine B<br>───────── ────── ─────────
editor ┌────────────┐ editor<br>│ │ op · · · │ ↑<br>│ save │ op · · · │ │<br>↓ │ op · · · │ daemon<br>daemon ── append ──▶│ op · · · │──▶ recv ───▶ │<br>│ op · · · │ ↓<br>└────────────┘ hello.txt<br>append-only, durable
opbox is built in Rust, and relies on several open<br>source libraries for core functionality:
S2<br>(serverless, or self-hosted) stores the shared<br>append-only log. Daemons append CRDT ops and read<br>ops produced by other daemons.
Turso<br>(SQLite-compatible) manages local semantic state,<br>including shadow CRDT documents and namespace<br>metadata.
yrs /Yjs<br>provides the CRDT data structures and update format.
turmoil<br>powers deterministic simulation tests for<br>multi-daemon sync scenarios.
Read the architecture doc →
CRDT ops in real-time
A file is created, edited in vim, and deleted while<br>ob spy (a debug tool) tails the shared log<br>directly from the opbox daemon.
FAQ
How is this different from Syncthing or Dropbox?
Those sync files as opaque blobs. When two<br>machines change the same file at once, one<br>version wins and the other becomes a conflict<br>copy. The trick of opbox is to sync CRDT diffs,<br>and model every document transparently in terms<br>of these, meaning files can merge automatically<br>and deterministically when edited concurrently.
How is this different from Google Docs or Live<br>Share?
These own the editor, so they are able to<br>directly interact with a sync scheme. opbox lets<br>you access the magic of multi-player editors but<br>on files that live on your device.
Why not P2P?
Using a shared log greatly simplifies sync. Each<br>daemon just needs to be able to append to and<br>read from a stream. As soon as an append is<br>acknowledged by the log, the daemon can move on<br>knowing the change is fully durable. This is<br>easier than P2P setups, where daemons would need<br>to own consensus themselves.
The log is<br>S2, which can be used in its serverless offering,<br>or you can run<br>s2-lite<br>yourself.
Can the log service read my files?
No. Workspace content in opbox is end-to-end<br>encrypted. When a workspace is created, a cipher<br>is randomly generated, and stored locally within<br>the database. This cipher must be provided<br>out-of-band (in addition to an S2 access-token)<br>to any other participant you want to share an<br>opbox workspace with.
What happens when two people edit the same file at<br>once?
Both edits survive. Text is modeled as a Yjs<br>CRDT document, so concurrent edits merge at<br>character granularity, kinda like...