andrewboldi11 downloadsTwo-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.
The Obsidian sync plugin that actually works on iOS — for vaults of any size, including images.
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.
| 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/commits → PATCH /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.
Status: submitted for review. Once accepted, install via Settings → Community plugins → Browse → Vault Sync (REST).
BRAT lets you install plugins straight from GitHub.
https://github.com/andrewboldi/obsidian-vault-sync
https://github.com/{you}/{repo} (or {you}/{repo})main (or whatever your default branch is)1 for near-realtime, 0 to disableThat'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.
| 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. |
.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.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.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.
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:
batchAllSettled to surface silent failuresMIT. See LICENSE.