Real-Time CRDT Sync

unlisted

by Yegor Usoltsev

Sync your vault in real time across devices through your own self-hosted server. Supports notes, folders, and attachments with offline editing, conflict recovery, and optional Git backup.

1 starsUpdated 17d agoMIT
View on GitHub

obsidian-crdt-sync

Build Status GitHub Release

⚠️ Early development — This plugin is in active early development. Use at your own risk and back up your vault before enabling it.

An Obsidian plugin that syncs your vault in real time across devices through your own self-hosted obsidian-crdt-sync-server. Supports notes, folders, and attachments with offline editing, conflict recovery, and optional Git backup.

Demo

What you get

  • Real-time sync for your whole vault: notes update across devices quickly, so your vault feels continuous instead of manually shuffled around.
  • Better handling of simultaneous edits: text notes use collaborative merging, which is much more forgiving than plain file-based sync.
  • Attachments included: images, PDFs, audio, and other binary files can sync alongside Markdown notes.
  • File and folder changes stay aligned: creates, renames, moves, and deletes propagate across devices, not just file contents.
  • Offline work still counts: keep editing without a connection and let pending changes catch up when you reconnect.
  • Safer conflict handling: if the plugin cannot apply a change cleanly, it preserves local data as .sync-conflict-<timestamp> copies instead of silently overwriting it.
  • Backups beyond sync: the companion server can also export your synced vault into Git, giving you commit history and a recovery path outside the live sync database.
  • A self-hosted stack: the companion server stores your vault state on infrastructure you control, with durable SQLite storage.
  • Practical recovery tools: the plugin shows sync state in Obsidian and lets you trigger a full resync from the command palette whenever you need to reconcile everything.

Installation

The plugin is not yet listed in the Obsidian Community Plugins directory. Install manually:

  1. Download main.js, manifest.json, styles.css, and versions.json from the latest release.
  2. Copy them to your vault's config plugins folder (usually <vault>/.obsidian/plugins/crdt-sync/).
  3. Enable the plugin under Settings → Community plugins.

Configuration

Open Settings → Real-Time CRDT Sync and fill in:

SettingDescription
Server URLWebSocket URL of your server, e.g. wss://sync.example.com. Use ws:// for localhost only.
Auth TokenShared secret matching AUTH_TOKEN on the server (min 32 chars). Stored in Obsidian's secure storage.
Debug loggingEnable verbose console logs for troubleshooting.

After saving, the plugin connects automatically. Sync status is shown in the status bar (CRDT Sync: connected, CRDT Sync: syncing, CRDT Sync: offline, CRDT Sync: error). Click the status bar item or use the command palette to run a full sync.

In practice

When a device connects, the plugin reconciles its local vault with the server and resumes syncing from there. Text notes are merged collaboratively, binary files are synced as attachments, local offline changes are replayed on reconnect, and files larger than 90 MB are skipped.

Risks and security

  • Data loss: This is early-stage software. Bugs in sync logic could corrupt or lose vault data. Always maintain independent backups.
  • Server trust: All vault content is transmitted to and stored on your self-hosted server in plaintext (beyond TLS). Whoever controls the server can read your entire vault.
  • TLS required: Always use wss:// for remote servers. The plugin enforces this and rejects ws:// for non-localhost addresses.
  • Auth token: The shared token is the only authentication factor. Use a strong random value generated during server setup and keep it secret. It is stored in Obsidian's secure storage and never written to the data file.
  • Protocol stability: The sync protocol and storage format may change in breaking ways between releases while the project is in early development.

Releasing

Create a release from a clean main branch:

bun run release patch
# or: bun run release minor
# or: bun run release major

The local release script updates manifest.json and versions.json, creates a Release: X.Y.Z commit, creates the matching X.Y.Z Git tag, and pushes both main and the tag to GitHub.

The GitHub Actions release workflow then runs GoReleaser on that tag. GoReleaser installs dependencies, builds main.js, creates the GitHub release, and uploads main.js, manifest.json, styles.css, and versions.json as release assets.

For a local dry run of the release packaging:

goreleaser release --snapshot --clean

Versioning

This project uses Semantic Versioning. Release tags use the same X.Y.Z version format as manifest.json and versions.json, as required by Obsidian community plugins.

Contributing

Pull requests are welcome. For larger changes, open an issue first so the release format, protocol compatibility, and migration impact can be discussed before implementation.

License

MIT

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.

Real-Time CRDT Sync | SimilarPlugins