sunwei66 downloadsSync your Obsidian vault across devices using CouchDB — with end-to-end encryption, selective sync, and live sync. Desktop & Mobile.
Free, open-source, end-to-end encrypted vault sync for Obsidian — Desktop & Mobile
Keep your Obsidian vault in perfect sync across all your devices — no subscription, no black box, no vendor lock-in.
You own your data. You control the server.
There are several ways to sync an Obsidian vault. Here's how they compare:
| MDFriday Sync | Obsidian Sync | Self-hosted LiveSync | Remotely Save | |
|---|---|---|---|---|
| Price | Free / Self-host | $8–$16 / month | Free | Free |
| Plugin open source | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes |
| Backend open source | ✅ Yes | ❌ No | ✅ (CouchDB) | ✅ (S3 / WebDAV) |
| Managed backend | ✅ License key only | ✅ Managed | ❌ Manual CouchDB setup | ❌ Manual setup |
| Fully self-hostable | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes |
| End-to-end encryption | ✅ AES-256 / HKDF | ✅ Yes | ✅ Yes | ⚠️ Optional |
| Real-time live sync | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
| Mobile support | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
| Hidden file sync | ✅ .obsidian/ folder |
✅ Yes | ✅ Yes | ❌ No |
| Conflict handling | ✅ Yes | ✅ Yes | ✅ Yes | ⚠️ Basic |
| Selective sync | ✅ Per file type | ✅ Yes | ⚠️ Limited | ❌ No |
MDFriday Sync builds on the battle-tested Self-hosted LiveSync core and adds what it lacks: a fully managed, open-source backend. With Self-hosted LiveSync you still have to provision and configure your own CouchDB server, manage user accounts, and handle updates yourself. With MDFriday Sync you enter a single license key and everything — database provisioning, authentication, connection credentials — is handled for you automatically. And if you prefer full control, the backend (hugoverse) is open source and self-hostable too.
MDFriday Sync uses CouchDB as the sync backend — a battle-tested, open-source database purpose-built for multi-device replication. Changes made on any device are pushed to a CouchDB server and instantly pulled to all other connected devices.
You have two options for the backend:
Activate a license at mdfriday.com. The backend is provisioned automatically — no CouchDB installation, no server configuration, no credential juggling. Just paste your license key and start syncing. Your data is encrypted on your device before it ever leaves.
Run the backend yourself using hugoverse — MDFriday's fully open-source backend. It bundles CouchDB setup and everything needed to run your own sync server.
# Spin up your own backend
git clone https://github.com/mdfriday/hugoverse
# follow the hugoverse README for setup
Or point the plugin directly at any existing CouchDB v3+ instance you manage.
.obsidian/ configuration in sync across devices, with smart per-device exclusions (workspace layout, cache, etc.)Search for MDFriday Sync in Obsidian's Community Plugins browser, or install manually by placing the files in your vault's .obsidian/plugins/mdfriday-sync/ folder.
CouchDB must be reachable from all your devices (desktop and mobile). For home servers, a VPN or reverse proxy with HTTPS is recommended.
Open Settings → MDFriday Sync and fill in:
| Field | Description |
|---|---|
| Server URL | Full CouchDB URL, e.g. https://myserver.com:5984 |
| Database name | Name of the CouchDB database (e.g. my-vault) |
| Username / Password | CouchDB credentials |
| Encryption passphrase | (Optional but recommended) Must be the same on every device |
Click Test Connection to verify.
⚠️ If you see "The remote database has been rebuilt", click Fetch from Server to re-sync a new device.
Control exactly what gets synced:
| Toggle | File types covered |
|---|---|
| Images | bmp png jpg jpeg gif svg webp avif |
| Audio | mp3 wav m4a 3gp flac ogg oga opus |
| Video | mp4 webm ogv mov mkv |
pdf |
|
| Themes | .obsidian/themes/ |
| Snippets | .obsidian/snippets/ |
| Plugins | .obsidian/plugins/ |
You can also define custom ignore patterns in gitignore format (e.g. attachments/, *.tmp, private/**) to exclude entire folders or file extensions.
.obsidian) SyncMDFriday Sync can keep your Obsidian configuration — themes, snippets, plugin settings — in sync across devices.
The following are excluded by default because they are device-specific or auto-regenerated:
| Excluded pattern | Why |
|---|---|
.obsidian/workspace |
Workspace state — differs per device |
.obsidian/workspace.json |
Workspace JSON — differs per device |
.obsidian/workspace-mobile.json |
Mobile workspace — differs per device |
.obsidian/cache |
Auto-regenerated, large, and device-specific |
node_modules/, .git/ |
Development artifacts |
plugins/mdfriday-sync |
This plugin's own data — device-specific |
git clone https://github.com/mdfriday/obsidian-sync
cd obsidian-sync
npm install
npm run build # → main.js + styles.css
npm run dev # watch mode for development
npm test # run unit tests
Requirements: Node.js ≥ 18
| Symptom | Solution |
|---|---|
| "Remote database has been rebuilt" | Click Fetch from Server on the affected device |
| Sync stopped but no error | Click Reconnect Sync in Settings |
| Files missing after sync | Click Rebuild vault from DB to re-write files from local cache |
| Files on server but not on new device | Use Download data from cloud on the new device |
| Encryption mismatch | Verify the passphrase is identical on all devices |
Apache-2.0 — see LICENSE.
Use it, fork it, self-host it — no restrictions.
This section discloses all external network requests made by the plugin, as required by the Obsidian plugin review process.
| Domain | Purpose | When | Required |
|---|---|---|---|
app.mdfriday.com |
License activation, authentication, usage tracking | Only when using MDFriday managed backend (Option A) | Only if using managed backend |
| User-configured CouchDB server | Vault synchronisation (all sync operations) | Whenever sync is active | Yes, for sync to work |
If you self-host (Option B with your own CouchDB or hugoverse), no requests are made to mdfriday.com. The plugin only contacts the CouchDB server you configure.
app.mdfriday.com (managed backend only)The following 6 API calls are made to app.mdfriday.com only when using the MDFriday managed backend:
| Call | Endpoint | Trigger |
|---|---|---|
| 1 | POST /api/login |
User clicks "Activate License" in settings |
| 2 | POST /api/license/trial |
User requests a free trial |
| 3 | POST /api/license/activate |
License key is entered and activated |
| 4 | GET /api/license/info |
Plugin startup (validates license, retrieves CouchDB credentials) |
| 5 | GET /api/license/usage |
Settings page opened (displays storage usage) |
| 6 | POST /api/license/usage/reset |
User resets usage counter in settings |
No vault content is ever sent to mdfriday.com. The plugin only retrieves CouchDB connection credentials from the license server and performs all vault sync directly with CouchDB.
btoa)The plugin uses btoa() in two places to encode CouchDB credentials as a standard HTTP Basic Authentication header (Authorization: Basic <base64(user:pass)>). This is the standard mechanism defined in RFC 7617. The encoded credentials are sent only to the user-configured CouchDB server. btoa is not used to hide API keys, URLs, or code payloads.
fetch instead of Obsidian's requestUrlObsidian recommends requestUrl for network requests. This plugin follows that recommendation everywhere except the internal PouchDB CouchDB replication adapter, where native fetch is the only viable option for the following technical reasons:
| Requirement | requestUrl |
native fetch |
|---|---|---|
AbortSignal support (request cancellation) |
❌ Not supported — RequestUrlParam has no signal field |
✅ Supported |
| Streaming response (resolve on headers, not full body) | ❌ Buffers entire body before resolving | ✅ Streams response |
| Honour PouchDB's internal cancel signal | ❌ Cannot — opts.signal is ignored |
✅ Combined via AbortSignal.any() |
PouchDB's CouchDB HTTP adapter requires AbortSignal to cancel in-flight _changes long-poll requests when the user stops sync. Without AbortSignal, requests cannot be cleanly cancelled — they would continue running in the background, leaking resources. The full-buffering behaviour of requestUrl also causes timeout failures for large bulk replication responses (_bulk_get, _bulk_docs) on cold start, because the response body is not available to PouchDB until the entire download completes.
All other network calls in the plugin (license API, CouchDB connection test, file publish) use requestUrl as recommended.
— LiveSync – multi-device synchronization