Vault Sync (REST)

by andrewboldi
5
4
3
2
1
Score: 35/100

Description

This plugin has not been manually reviewed by Obsidian staff. Two-way sync with a GitHub repo via REST API. Works on iOS for vaults of any size including images, where git-protocol plugins crash from WebView memory limits.

Reviews

No reviews yet.

Stats

stars
downloads
0
forks
1
days
NaN
days
NaN
days
0
total PRs
0
open PRs
0
closed PRs
0
merged PRs
0
total issues
0
open issues
0
closed issues
0
commits

Latest Version

Invalid date

Changelog

README file from

Github

Vault Sync (REST)

The Obsidian sync plugin that actually works on iOS — for vaults of any size, including images.

Why this exists

The popular obsidian-git plugin uses isomorphic-git, which loads entire packfiles into memory during clone and pull. On iOS, the WKWebView heap kills Obsidian once the packfile pressure adds up — silently. No error, just an "Obsidian is loading…" splash and a wiped .obsidian/ folder.

This is a documented, multi-year, unfixed issue (#642, #1012, #475). The maintainer's own README warns: "The git implementation on mobile is very unstable!"

The fix isn't in JavaScript. It's in the protocol: stop using git's wire protocol on iOS. Use GitHub's REST API instead — fetch one file at a time, and memory pressure stays bounded by the largest single file rather than the whole vault.

This plugin syncs your Obsidian vault to a GitHub repository without ever invoking git's wire protocol, while still producing real git commits on the GitHub side.

What it does

Operation How
Seed (initial download) GET /git/trees/{sha}?recursive=1 for the file list, then GET /contents/{path} per file (raw bytes, no base64 overhead)
Pull GET /compare/{old}...{new} for the file-level diff, then per-file fetch of only the changed ones
Push POST /git/blobs per changed file → POST /git/trees (delta on base_tree) → POST /git/commitsPATCH /git/refs/heads/{branch}. One atomic commit.
Auto-sync setInterval runs pull then push every N minutes, silent unless something errors

Memory use during any operation: bounded by your largest single file, not your vault size. A 1GB vault syncs as cleanly as a 1MB one.

Install

Stable (Community plugins)

Status: submitted for review. Once accepted, install via Settings → Community plugins → Browse → Vault Sync (REST).

BRAT lets you install plugins straight from GitHub.

  1. Install BRAT from Community plugins.
  2. BRAT settings → Add Beta plugin → paste:
    https://github.com/andrewboldi/obsidian-vault-sync
    
  3. Enable Vault Sync (REST) under Community plugins.
  4. BRAT auto-updates the plugin when new releases are published.

Setup

  1. Create a GitHub Personal Access Token (fine-grained recommended):
    • Resource owner: your account
    • Repository access: Only select repositories → pick the vault repo
    • Repository permissions: Contents: Read and write
  2. Settings → Vault Sync (REST):
    • GitHub Personal Access Token: paste the token
    • Repository URL: https://github.com/{you}/{repo} (or {you}/{repo})
    • Branch: main (or whatever your default branch is)
    • Auto-sync interval (minutes): 1 for near-realtime, 0 to disable
  3. Run Vault Sync: Seed from GitHub (command palette).

That's it. Edit on phone → 1 minute later it's a real commit on GitHub. Edit on desktop → 1 minute later it's on phone.

Commands

Command What it does
Vault Sync: Seed from GitHub Initial download of the entire repo. Run once after install.
Vault Sync: Pull from GitHub Fetch incremental changes since last sync.
Vault Sync: Push to GitHub Detect local changes, upload as one atomic commit.
Vault Sync: Sync now Pull then push. Same as the ribbon icon.

How conflict handling works (and doesn't)

  • Push refuses if remote diverged since your last pull. Run Pull then retry Push. This is intentional — the plugin won't silently overwrite remote work.
  • Pull refuses on diverged history for now. Reseed if you really need to discard local state.
  • Same file edited on both sides: last-pull-then-push wins. There is no merge engine. For prose vaults this is rare and tolerable; for collaborative editing, use desktop git for resolution.

What gets skipped (never pushed)

  • .obsidian/plugins/** — plugin code/configs are per-device. Each install pulls them fresh from BRAT/community store. Avoids leaking credentials in plugin data.json files.
  • .obsidian/workspace*, .obsidian/cache, .obsidian/appearance.json — UI/UX state, per-device.
  • .trash/, .DS_Store, *.tmp
  • The plugin's own settings file (your PAT lives in .obsidian/plugins/vault-sync-rest/data.json — protected by the rule above)

What still syncs from .obsidian/:

  • .obsidian/community-plugins.json — list of which plugins to enable (so each device knows what to install)
  • .obsidian/hotkeys.json, themes, etc.

Limits & caveats

  • GitHub-only. No GitLab/Bitbucket/Gitea support. The Git Data API shape varies enough between hosts that supporting all of them would be a separate project.
  • Files >100 MB: GitHub's API hard-caps individual files at 100 MB. For larger files, use Git LFS (out of scope) or store them outside the vault.
  • >100k files: Git tree API caps at ~100k entries per recursive call. Vaults beyond that need pagination, not implemented.
  • Compare API caps at 300 files per call. If a single push between syncs touches more than 300 files, the plugin warns; reseed to recover.
  • Phone has no local git history, just the last-known SHA pointer. Real git history lives on GitHub and on your desktop. This is a feature, not a bug — phone storage stays small.
  • No conflict merging. See above.

Architecture

iOS Obsidian                       GitHub                       Desktop Obsidian
─────────────                      ──────                       ─────────────────
Vault Sync (REST)  ──HTTPS──>  api.github.com  <──git──  obsidian-git / git CLI
                                      │
                                  real git commits
                                  in repo history

The GitHub repository is the single source of truth. Mobile and desktop both read/write through it independently. Mobile uses REST/Git-Data APIs; desktop uses normal git. They never need to know about each other.

Built in one evening

This plugin was designed and built in a single session after spending hours debugging why obsidian-git wouldn't clone an Obsidian vault on iOS. The diagnostic path was:

  1. Confirmed the bug → found upstream isomorphic-git issues → patched batchAllSettled to surface silent failures
  2. Discovered the real root cause was iOS WebView heap exhaustion, not silent JS errors
  3. Pivoted to the only viable architecture for iOS: per-file REST API instead of git wire protocol
  4. Phase 1 (seed) → Phase 2 (pull) → Phase 3 (push) → Phase 4 (auto-sync), shipped iteratively

License

MIT. See LICENSE.