Bidirectional vault sync for Neovim — WebDAV / Nextcloud / S3 / Dropbox / Google Drive and every other rclone remote. The same feature set as the Remotely Save desktop plugin, without the app.
Registers as a sync backend into obsidian.nvim via its public register() API, so :Obsidian sync, on_write, continuous mode, statusline and the menu picker all work with zero changes to obsidian.nvim.
🌐 Any remote: WebDAV, Nextcloud/ownCloud, S3, Dropbox, Google Drive, OneDrive, SFTP, SMB, local folders — rclone handles every protocol and TLS, no cloud-specific code shipped.
🔄 Bidirectional sync: rclone bisync — deterministic two-way sync by size + modtime. No silent data loss: conflicts produce Note.md.conflict1 / Note.md.conflict2.
🧙 Setup wizard in Neovim: enter your WebDAV URL and credentials directly, the rclone remote is created automatically. No terminal required.
⚡ Three triggers: on_write — debounced sync on save (2 s). continuous — timer loop every N seconds. manual — only when you ask.
📊 Floating progress window: animated spinner, green checkmark / red error, auto-closes. Mirroring the UX of lazy.nvim / mason.nvim.
📏 Statusline component: drop-in for lualine, heirline, mini.statusline, feline, windline, or plain vim statusline. Auto-refreshes via User ObsidianSyncChanged.
💾 Persistent config: vault→remote mappings survive restarts (stdpath("data")/obsidian-sync.json). Passwords live only in rclone.conf (obscured).
🧪 Tested: 23 unit tests via mini.test, headless smoke test against real Nextcloud WebDAV.
🖥️ Cross-platform: macOS, Linux, Windows. rclone is the only binary dependency.
- Neovim ≥ 0.10 (
vim.system/vim.uv) - obsidian.nvim (community fork)
rcloneon$PATH— install- macOS:
brew install rclone - Linux:
apt install rclone/pacman -S rclone - Windows:
winget install rclone
- macOS:
-- lazy.nvim
{
"obsidian-nvim/obsidian.nvim",
lazy = true,
opts = {
workspaces = { { name = "vault", path = "~/my-vault" } },
sync = { enabled = true, backend = "rclone", trigger = "on_write" },
},
dependencies = {
{
"your-user/obsidian-sync.nvim",
config = function()
require("obsidian-sync").setup()
end,
},
},
}Open a markdown file → :Obsidian sync setup (or the auto-wizard on first run) → pick WebDAV / Nextcloud → enter URL + credentials → done. Saving a note triggers sync.
Menu: start, pause, one-shot sync, setup wizard, disconnect, open log.
Shortcut — opens the setup wizard if no vault is linked, the menu otherwise.
Diagnostics: rclone version, linked vaults, obsidian.nvim status.
Standard Neovim health check (auto-discovered from health.lua).
| Doc | Content |
|---|---|
| Sync | Full sync reference: triggers, options, conflicts, quirks |
| Setup | Setup wizard walkthrough — WebDAV, existing remotes, local folders |
| Statusline | Drop-in integrations for lualine / heirline / mini / feline / windline |
| Backends | How to write a custom sync backend |
require("obsidian-sync").setup {
-- vault root → rclone target
remotes = { ["/path/to/vault"] = "s3:my-bucket/vault" },
-- seconds between syncs in continuous mode
check_interval = 300,
-- retry once with --resync on first connect
auto_resync = true,
-- log a friendly notice on --resync (instead of ERROR)
safe_resync = true,
-- show vim.notify on sync start / complete
notify_events = true,
-- show floating spinner window during sync
progress_win = true,
-- rclone bisync flags
bisync = {
exclude = { ".DS_Store", "*.bisync*", ".bisync/**" },
args = {}, -- e.g. { "--max-delete=20", "--fast-list" }
},
}obsidian.nvim sync menu / triggers / statusline
│
▼ sync.register("rclone", backend)
obsidian-sync.nvim (backend.lua)
│
▼ rclone bisync
rclone ── S3 / WebDAV / SFTP / ...
rclone bisync is a one-shot deterministic tool that compares two directory trees by size + modtime, copies differences in both directions, and on conflict keeps both versions — zero data loss, same behaviour as Remotely Save.
The plugin implements obsidian.nvim's obsidian.sync.Backend contract — start, pause, sync_once, setup, disconnect, log, ws_formatter. The contract is public; you can write your own backend with require("obsidian.sync").register("my-name", my_backend).
Continuous mode is a vim.uv timer loop that runs bisync each interval. One-shot syncs run as async vim.system processes; rclone output streams into obsidian.nvim's sync log and updates its statusline component.
make test # downloads mini.test, runs 23 unit tests headlessMIT