Syncing devices¶
Every device holds a full replica of the workspace as CRDT documents (Loro). Changes merge by construction: two devices can edit the same course offline for a week and still converge without a conflict dialog. Syncing simply means exchanging updates, and any of the three channels below can carry them. A device can use all three.
Through a server¶
Connect the app to a self-hosted server in
Settings > Backup & sync > Server. Browsers are always connected to the
server that serves them. From then on the device pushes its changes to the
server's log and pulls what other devices pushed. This happens
automatically, shortly after every change and on every launch.
The server never interprets your data. It stores opaque update blobs per account, plus the uploaded file bytes, and a background job folds long logs into snapshots so they never grow unbounded. See Install a server.
Over the local network¶
Two desktop apps on the same network find each other automatically and can sync directly, without a server or internet access. Open the Sync page from the top bar: nearby devices appear on their own, and pressing Sync next to one exchanges exactly the document updates and files the other one lacks. Turn on Auto-sync with nearby devices on that page to keep the devices in step in the background, without pressing Sync each time.
A few things to know:
- Direct device-to-device sync runs in the desktop and mobile shells, which host the discovery socket. A plain browser tab cannot advertise itself, so it syncs through a server or file packs instead.
- Both devices must be on the same network, and the network must allow multicast. Guest and hotel networks often block it.
- On iOS the system asks for the local network permission the first time.
- The connection is not authenticated within your network, so sync on networks you trust.
File packs¶
Settings > Backup & sync > Backup exports the whole workspace as one
.synapse file: courses, chapters, annotations, exercises, attempts, lexicon
and the documents themselves. Importing it on any device merges it in;
nothing gets overwritten and identical content is stored once. The same
file serves three purposes:
- a backup you can store anywhere,
- a way to sync two machines that share no network,
- a way to move your workspace into a fresh install.
The export holds only the current state by default, which keeps the file small. Tick Include history to carry the full change history too (larger file), so the importing device also gets the timeline shown on the History page.
What is inside a .synapse file¶
A .synapse file is a plain zip, so any archive tool can open it to see
what it holds. The layout is small and stable:
manifest.json { version, docs: [...], blobs: [...] }
docs/workspace.snapshot the courses, chapters, links, lexicon and
exercises, as one Loro CRDT snapshot
docs/attempts.snapshot your exercise attempts and progress
docs/ann:<id>.snapshot one per annotated document: its highlights,
drawings and notes
blobs/<sha256> the document files themselves (PDFs, etc.),
named by the hash of their content
The snapshots are CRDT documents, which is why importing merges rather than
overwrites: two devices editing offline both fold in cleanly. Files live under
blobs/ addressed by content hash, so a document shared across courses is
stored once, and re-importing the same file is free. Import detects a pack by
its manifest.json, not its name, so a .synapse file renamed to .zip (or
an older .zip export) still imports.
Troubleshooting¶
| Symptom | Likely cause |
|---|---|
| Nearby devices stays empty | The devices are on different networks, or the router blocks multicast. Both apps must be running. |
| Server sync stopped | The session expired. Reconnect in Settings > Backup & sync > Server. For native apps, check CORS_ORIGINS on the server. |
| A document opens without its PDF | The file bytes have not reached this device yet. Sync once with a device that has them, or import a file pack that includes files. |
| Two devices briefly show different orders | Updates are still in flight. Both settle on the same order after the next sync. |