Skip to main content

obsidian-sync

obsidian-sync keeps a local Obsidian vault synchronized with a Synology Drive folder in near real-time.

Primary use case:

  • macOS local vault -> Synology Drive folder: /Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync
  • Windows Obsidian opens the same Synology folder (for example C:\Users\<user>\SynologyDrive\obsidian-sync)

Features

  • Bidirectional sync (source_vault <-> synology_vault)
  • Real-time watch mode + periodic reconciliation
  • Single-instance lock (prevents concurrent sync writers)
  • First-run safe behavior with backups before overwrite/delete
  • Conflict policies (latest, source, target, manual) + conflict history/restore commands
  • Snapshot history and deleted-file recovery commands
  • Activity log of sync operations (copy/delete/conflict/restore/error)
  • Batch conflict resolver (resolve-conflicts)
  • Device-state excludes by default (workspace.json, caches, plugin temp files)
  • Fine-grained vault settings sync toggles (.obsidian settings categories)
  • Selective attachment-type sync toggles (images/audio/videos/PDF/other)
  • Rules engine (folder glob, extension, markdown tag, per-device profile)
  • Rename/move mirroring across sides
  • Delta patch sync for large files (partial block updates)
  • Optional encrypted cloud vault mode (vault_encryption_enabled)
  • Optional encryption for backups/snapshots/conflict copies (passphrase via env var or CLI flag)
  • Health command, integrity audit, optional webhook alerts
  • Multi-vault watcher orchestration (watch-all)
  • SQLite state tracking for deterministic updates/deletes
  • Windows-safe filename collision detection (case-only conflicts)

Install (macOS)

cd /Users/den/Desktop/obsidian-sync
python3 -m venv .venv
source .venv/bin/activate
pip install .

Install from PyPI (after you publish):

pip install obsidian-synology-sync

Install with encryption support:

pip install 'obsidian-synology-sync[crypto]'

Quick Setup (New Users)

Note: scripts/macos/setup_new_user.sh and scripts/windows/setup_new_user.ps1 are repository files. If you installed only via pip, clone this repository to use these setup helpers.

Passphrase (required for encrypted mode)

The passphrase is user-defined. It is not auto-generated by obsidian-sync or Synology. All devices must use the exact same value.

Recommended for manual runs:

obsidian-sync --config /path/to/obsidian-sync.toml watch --passphrase 'your-strong-passphrase'
obsidian-sync --config /path/to/obsidian-sync.toml watch --passphrase-file ~/.obsidian-sync-passphrase

--passphrase-file reads UTF-8 text and ignores one trailing newline.

Set manually on Windows:

setx OBSIDIAN_SYNC_PASSPHRASE "your-strong-passphrase"

Set manually on macOS:

export OBSIDIAN_SYNC_PASSPHRASE='your-strong-passphrase'

Read current value:

[Environment]::GetEnvironmentVariable("OBSIDIAN_SYNC_PASSPHRASE","User")
echo "$OBSIDIAN_SYNC_PASSPHRASE"

macOS user setup (encrypted cloud vault + auto-start)

cd /Users/den/Desktop/obsidian-sync
pip install 'obsidian-synology-sync[crypto]==0.2.3'
scripts/macos/setup_new_user.sh \
  --source "/ABSOLUTE/PATH/TO/YOUR/LOCAL/OBSIDIAN-VAULT" \
  --target "/Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync" \
  --config "/Users/den/Desktop/obsidian-sync/obsidian-sync.toml" \
  --passphrase "your-strong-passphrase"

What this does:

  • creates config if missing
  • enables encrypted cloud-vault mode
  • installs/restarts launchd auto-start job
  • runs one immediate sync

Windows user setup (encrypted cloud vault + auto-start)

cd C:\path\to\obsidian-sync
pip install "obsidian-synology-sync[crypto]==0.2.3"
powershell -ExecutionPolicy Bypass -File .\scripts\windows\setup_new_user.ps1 `
  -SourceVault "C:\Users\<user>\ObsidianLocalVault" `
  -SynologyVault "C:\Users\<user>\SynologyDrive\obsidian-sync" `
  -ConfigPath "C:\Users\<user>\obsidian-sync.toml" `
  -Passphrase "your-strong-passphrase"

What this does:

  • creates config if missing
  • enables encrypted cloud-vault mode
  • sets passphrase env var and creates a logon scheduled task
  • starts watcher immediately

Initialize

obsidian-sync init \
  --source "/ABSOLUTE/PATH/TO/YOUR/OBSIDIAN-VAULT" \
  --target "/Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync" \
  --windows-path "C:\\Users\\<user>\\SynologyDrive\\obsidian-sync"

This creates:

  • Config: obsidian-sync.toml
  • State DB: .obsidian-sync-state/state.db

Run

One-time sync:

obsidian-sync sync-now

One-time sync with encrypted mode passphrase flag:

obsidian-sync sync-now --passphrase 'your-strong-passphrase'

Preview only:

obsidian-sync sync-now --dry-run

Continuous sync:

obsidian-sync watch

Continuous sync with passphrase file:

obsidian-sync watch --passphrase-file ~/.obsidian-sync-passphrase

Continuous sync for multiple vault configs:

obsidian-sync watch-all --configs /path/a.toml /path/b.toml

Status:

obsidian-sync status

List conflict history:

obsidian-sync conflicts

Restore a conflict copy:

obsidian-sync restore-conflict <ID>
obsidian-sync restore-conflict <ID> --side source

Batch resolve open conflicts:

obsidian-sync resolve-conflicts --policy latest
obsidian-sync resolve-conflicts --policy source

List snapshots:

obsidian-sync snapshots
obsidian-sync snapshots --path "Projects/plan.md"

List deleted-file recoveries:

obsidian-sync deleted-files

Restore a snapshot/deleted record:

obsidian-sync restore-snapshot <SNAPSHOT_ID>
obsidian-sync restore-snapshot <SNAPSHOT_ID> --side target

Show activity log:

obsidian-sync activity --limit 100
obsidian-sync activity --path "Projects/plan.md"

Health + integrity audit:

obsidian-sync health
obsidian-sync audit
obsidian-sync audit --repair

How Windows sync works

Recommended setup:

  1. Use Synology Drive client on Windows.
  2. Keep obsidian-sync watch running on both devices.
  3. Open Obsidian on each device at its local source_vault.

Mode behavior:

  • Plain mode (vault_encryption_enabled = false): you can open the Synology local folder directly as a vault.
  • Encrypted cloud-vault mode (vault_encryption_enabled = true): do not open Synology folder directly. Open local source_vault and let obsidian-sync decrypt/encrypt between local vault and Synology.

Backup and conflict behavior

  • Before overwrite/delete, existing files are backed up under:
    • <synology_vault>/.obsidian-sync-backups/
  • If both sides changed before sync:
    • A .conflict-... copy is created for the losing side.
    • Newer file (mtime) wins for the main path.
    • Conflict entries are stored and can be listed with obsidian-sync conflicts.
    • Restores are supported with obsidian-sync restore-conflict.

Device-state excludes (default)

By default, device-specific noise is excluded from sync:

  • .obsidian/workspace.json
  • .obsidian/workspaces.json
  • .obsidian/cache/**
  • .obsidian/plugins/*/cache/**
  • .obsidian/plugins/*/tmp/**

You can disable this in obsidian-sync.toml by setting:

[sync]
exclude_device_state = false

Fine-Grained Sync Controls

obsidian-sync.toml supports the following feature toggles:

[sync]
# Vault configuration
sync_main_settings = true
sync_appearance_settings = true
sync_themes_and_snippets = true
sync_enabled_plugins = true
sync_hotkeys = true

# File type selection
sync_images = true
sync_audio = true
sync_videos = true
sync_pdfs = true
sync_other_types = true

# Conflict + performance
conflict_policy = "latest" # latest|source|target|manual
delta_sync_enabled = true
delta_min_file_size_bytes = 8388608
delta_chunk_size_bytes = 1048576
delta_max_diff_ratio = 0.5
vault_encryption_enabled = false
encryption_enabled = false
encryption_passphrase_env = "OBSIDIAN_SYNC_PASSPHRASE"
encryption_kdf_iterations = 600000

# Integrity + alerts
integrity_audit_interval_seconds = 3600.0
integrity_auto_repair = false
alerts_webhook_url = ""
alerts_on_conflict = true
alerts_on_error = true
health_stale_after_seconds = 300.0

Example: disable videos and PDFs:

[sync]
sync_videos = false
sync_pdfs = false

Enable encrypted backups/snapshots/conflict copies:

[sync]
encryption_enabled = true
encryption_passphrase_env = "OBSIDIAN_SYNC_PASSPHRASE"

Then export the passphrase before running sync:

export OBSIDIAN_SYNC_PASSPHRASE='your-strong-passphrase'
obsidian-sync watch

Or pass it directly for that run:

obsidian-sync watch --passphrase 'your-strong-passphrase'
obsidian-sync watch --passphrase-file ~/.obsidian-sync-passphrase

Main vault files remain plain for Obsidian compatibility; encrypted mode applies to recovery artifacts stored under .obsidian-sync-backups.

Encrypted Cloud Vault Mode

If you want Synology Drive files encrypted at rest (instead of plain .md), enable:

[sync]
vault_encryption_enabled = true
encryption_passphrase_env = "OBSIDIAN_SYNC_PASSPHRASE"

Behavior:

  • Local source_vault stays plaintext (Obsidian opens this directly).
  • Synology synology_vault stores encrypted files as *.osync.enc.
  • Run obsidian-sync on every device (macOS/Windows) with the same passphrase (env var or CLI flag) so each device can decrypt to its local vault.

Recovery and Activity

  • snapshots includes version-like copies captured during sync and backup events.
  • deleted-files shows deleted note/attachment recoveries.
  • restore-snapshot restores any snapshot or deleted entry to source/target.
  • activity shows a durable log of sync operations and restore actions.

Rules Engine

Use [sync] and profile blocks to control selection by path/extension/tag:

[sync]
device_profile = "windows"
rules_include_globs = ["Projects/**", "Inbox/**"]
rules_exclude_globs = ["Archive/**"]
rules_include_extensions = [".md", ".canvas", ".pdf"]
rules_exclude_extensions = [".tmp"]
rules_include_tags = ["work"]
rules_exclude_tags = ["private"]

[profiles.windows]
rules_exclude_globs = [".obsidian/plugins/heavy-plugin/**"]

Rules are merged from [sync] + [profiles.<device_profile>].

Scope Note

This project implements local/Synology-based equivalents of Obsidian Sync workflow features. Hosted service features from Obsidian's cloud product are out of scope here:

  • Obsidian account authentication and hosted relay infrastructure
  • Shared vault invite/permission management UI
  • Cloud-managed end-to-end key exchange and recovery UX

Auto-start on login

macOS (launchd):

scripts/macos/setup_new_user.sh \
  --source "/ABSOLUTE/PATH/TO/YOUR/LOCAL/OBSIDIAN-VAULT" \
  --target "/Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync" \
  --config "/Users/den/Desktop/obsidian-sync/obsidian-sync.toml" \
  --passphrase "your-strong-passphrase"

Windows (Task Scheduler):

powershell -ExecutionPolicy Bypass -File .\scripts\windows\setup_new_user.ps1 `
  -SourceVault "C:\Users\<user>\ObsidianLocalVault" `
  -SynologyVault "C:\Users\<user>\SynologyDrive\obsidian-sync" `
  -ConfigPath "C:\Users\<user>\obsidian-sync.toml" `
  -Passphrase "your-strong-passphrase"

Build and publish (pip distributable)

Build and validate distributions:

cd /Users/den/Desktop/obsidian-sync
scripts/release/build_dist.sh

Upload:

# TestPyPI first
scripts/release/publish.sh testpypi

# Production PyPI
scripts/release/publish.sh pypi

twine uses TWINE_USERNAME and TWINE_PASSWORD (or keyring) for authentication.

Notes

  • Avoid storing two files that differ only by case (for Windows compatibility).
  • Keep file names and paths stable between macOS and Windows.
  • For very large vaults, first sync may take time.

Metadata

Release files for obsidian-synology-sync 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for obsidian-synology-sync 0.2.3
File Size Uploaded Provenance
obsidian_synology_sync-0.2.3.tar.gz 37.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for obsidian-synology-sync 0.2.3
File Interpreter ABI Platform
obsidian_synology_sync-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 72.7 kB

Release files / obsidian_synology_sync-0.2.3.tar.gz

Download URL obsidian_synology_sync-0.2.3.tar.gz
Size 37.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d15dd6a940c2f2c1e0096cd41efa11d06691a4ef1546e9453e472e46e2bd1c93
BLAKE2b-256 checksum
How to use checksums
2fd8ef7fa8a55592248d22da9157c24c98cb24b045ec8b78a668bdf251a9987c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release files / obsidian_synology_sync-0.2.3-py3-none-any.whl

Download URL obsidian_synology_sync-0.2.3-py3-none-any.whl
Size 35.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5178713fb1c2f6ab984c458ee587d0ab29b34f7f621506e9017ee5649a1f5307
BLAKE2b-256 checksum
How to use checksums
657de8acdd2ba84e1ce4544df98e646eda51021e7e04e69965c83da6e8a4ecb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Security for obsidian-synology-sync 0.2.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page