A vault is a folder of plain files, so syncing it is mostly a server, a manifest and encryption, and an agent can write all three over a weekend. The slow part is trust: conflicts, renames and deletions have to be right before you point it at notes you care about, and the plugin needs a real phone to test on. Free routes such as iCloud, Syncthing or Git already exist, so a build makes sense only if you want your own end-to-end encrypted server.
Before you buildObsidian is free without Sync. If your devices are all Apple, iCloud Drive may be enough; if they are mostly desktops, Syncthing is free.
Build me a self-hosted sync service for an Obsidian vault to replace Obsidian Sync. Requirements:
- One TypeScript monorepo on Node.js 22 with npm workspaces: `core/` (the sync engine, no Obsidian
imports), `server/` and `plugin/` (an Obsidian community plugin built with esbuild that runs on
mobile: no Node APIs, HTTP through Obsidian's requestUrl).
- Server: Fastify + better-sqlite3 in ./data/sync.db, file bodies in ./data/blobs/<sha256>.
POST /v1/changes takes the client's manifest and returns what changed; PUT and GET /v1/blob/:hash move
bodies. One bearer token (SYNC_TOKEN in .env); refuse everything without it; listen on 127.0.0.1
unless HOST is set.
- Encryption: the plugin encrypts file contents and paths with AES-256-GCM through WebCrypto, using a
key derived from a passphrase with scrypt (`@noble/hashes`). The server only sees ciphertext and
opaque ids. The passphrase never leaves the device, so losing it loses the vault; say so in the README.
- Engine: keep a local manifest {path, hash, mtime, deleted} from the last sync and compare it with the
device and the server. If both sides changed a file, keep both: the second copy becomes
"<name> (conflict <device> <date>).md". Deletions are tombstones kept for 30 days.
- Plugin: sync at startup, 5 seconds after a file is saved, and from a "Sync now" command; a status bar
item with the last sync time and error count; a settings tab for server URL, token, passphrase, device
name and ignore globs (default `.obsidian/workspace*.json`).
- Version history: the server keeps the last 20 versions of each file for 30 days; a command lists a
file's versions and restores one.
- Tests with vitest on the engine: two devices doing edit, rename, delete-versus-edit, conflict and
offline catch-up, plus a test that the server never receives a plaintext path or body.
- Single user. No accounts, no telemetry, local-first. Sync only runs while Obsidian is open, as in the
official service.
- Out of scope: shared vaults, live cursors, selective sync, a headless mode.
- README: copying main.js and manifest.json into .obsidian/plugins/, running the server behind a tunnel
or a VPS with HTTPS, and a plain warning to keep a separate backup, because sync is not a backup.Opens your agent with the prompt filled in, you press enter. Or copy it and paste it into an empty folder.
The first prompt builds the core. Run these one at a time in the same folder to grow it into your own Obsidian Sync.
Add backups to the sync server in this folder. Requirements: - A command `npm run backup` that writes ./backups/YYYY-MM-DD.zip with the SQLite file (using the online backup API, not a plain copy) and every referenced blob. - Schedule it nightly with node-cron at a time set in .env and keep the newest 14 archives. - A `restore` command that unpacks an archive into an empty data folder and verifies every blob's sha256. - Update the README.
Add selective sync to the Obsidian plugin in this folder. Requirements: - Per device settings: skip files larger than N MB, skip folders by glob, and skip file types (images, audio, video, PDF). - Skipped remote files appear in the status bar count and are downloaded only when requested from a command palette entry "Fetch skipped file". - Never delete a skipped remote file because it is missing locally; add a test for that. - Update the README.
Add a headless client to the sync project in this folder. Requirements: - A Node CLI `vault-mirror --server URL --dir ./vault` using the core engine, with the token and passphrase from .env, that syncs once or watches the folder with chokidar. - It must use the same encryption, manifest and conflict naming as the plugin, so both can sync with one server. - Exit non-zero on any error and log one line per file changed. - Add an integration test running the CLI against the test server. - Update the README with a systemd unit example.
Forum threads and guides describe Sync as the low-maintenance choice when devices are mixed, with end-to-end encryption and no setup, and the revenue keeps a user-supported project going. Obsidian's own docs point Apple-only users to iCloud and list Syncthing as unsupported on iOS, which is where Sync earns its price.
Estimate · A tunnel is free and a small VPS costs about what Sync Standard does ($5 a month, or $4 billed yearly), so the gain is control, not money. The build is token usage on your agent plan.
Checked 2026-10-14 against Obsidian Sync's docs: 1, 2, 3, 4, 5
| Plan | Monthly | Annual, per month | What you get |
|---|---|---|---|
| Sync Standard | $5/user | $4/user | 1 synced vault, 1 GB total storage, 5 MB maximum file size, 1 month of version history, unlimited devices. |
| Sync Plus | $10/user | $8/user | 10 synced vaults, 10 GB total storage (upgradable to 100 GB), 200 MB maximum file size, 12 months of version history. |
Obsidian itself is free with no sign-up; Sync and Publish are the paid add-ons, and there is no free Sync plan.
Kinda. The core is a weekend build with the prompt on this page, but real gaps remain: Shared vaults for working with other people, A version-history viewer and file recovery tied to the app.
About $5 a month on the Sync Standard plan per seat, $60 a year (checked 2026-10-14).
Shared vaults for working with other people; A version-history viewer and file recovery tied to the app; Selective sync and per-device settings sync done for you; Headless Sync and regional servers; Priority support and a service whose uptime someone else watches. If any of those matter to you, keep paying.
Yes: Syncthing (open source), Syncthing-Fork (open source), Self-hosted LiveSync (open source).