Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian
GitHub

GitHub Vault Relay

Nguyễn An KhangNguyễn An Khang49 downloads

A conservative GitHub bridge for Obsidian Mobile - without running Git on the phone.

Add to Obsidian
  • Overview
  • Scorecard
  • Updates17

A conservative GitHub sync bridge for Obsidian mobile and desktop, without running Git on the phone.

Current canonical baseline

  • Release: 1.0.8 (manifest, package, tag, and main agree after release).
  • Minimum Obsidian version: 1.11.4.
  • Mobile support: enabled (isDesktopOnly: false).
  • Automated evidence: 45 Vitest test files and 496 passing tests in the current tree.
  • Latest local quality gate: npm run verify PASS on 2026-09-07 (lint, typecheck, test, build).
  • The production bundle is generated by npm run build; npm run verify is the canonical gate.
  • Release-gate physical acceptance is PASS on Windows and iPhone for settings, hidden paths, normal files, and restart behavior. See the manual matrix for the recorded sign-off.

What it does

Vault Relay connects one configured Obsidian vault/repository/branch to GitHub over HTTPS. It uses Obsidian's requestUrl() API and GitHub's REST and Git Data APIs; the core sync engine does not depend on native Git, child_process, or isomorphic-git.

The product is intentionally conservative:

  • Sync is user-triggered; there is no background sync or sync-on-save.
  • A unified Sync action plans, pulls safe remote changes, replans, pushes safe local changes, and reports the result.
  • A Safe Push batch creates one Git commit and updates the branch with force: false.
  • Ambiguous changes are preserved for review instead of silently overwritten.
  • Local and remote deletion are classified only when a synchronized baseline proves what existed before.
  • Moves are paired only by exact content SHA; otherwise they remain separate add/delete candidates.
  • Files larger than 25 MiB are skipped by policy.
  • Optional Desktop Git Integration (Declarative Handoff): For vaults that also contain a .git repository on Desktop, an optional setting writes a declarative signal file (.obsidian/github-vault-relay/git-handoff.json) upon successful sync. Companion helper scripts (scripts/git-handoff.ps1 for Windows, scripts/git-handoff.sh for macOS/Linux) consume this signal outside Obsidian to run git fetch and git reset --mixed <remoteCommitSha>, cleanly advancing local Git metadata without running any child processes inside Obsidian or re-downloading working tree files. This is strictly opt-in, non-blocking, and 100% hidden on mobile.

Recommended Architecture: Standalone Vault vs. Colocated Git Repository

Vault Relay is designed to connect Obsidian directly to GitHub over HTTPS without requiring Git on the device. Understanding how your local filesystem interacts with GitHub avoids unnecessary operational complexity.

flowchart TD
    subgraph ModelA["Model A: Standalone Vault (Recommended Best Practice)"]
        PhoneA["Mobile (iPhone / Android)"] -->|HTTPS API| GHA["GitHub Repository"]
        DesktopA["Desktop Obsidian (Pure Vault, no .git)"] -->|HTTPS API| GHA
        GHA -.->|git pull on demand| ExternalRepo["Separate Git Clone Directory (e.g. ~/Developer/vault-backup)"]
    end

    subgraph ModelB["Model B: Colocated Vault (Vault directory contains .git)"]
        DesktopB["Desktop Obsidian"] -->|HTTPS API Push| GHB["GitHub Repository"]
        DesktopB -.->|git-handoff.json| Handoff["External Script: git fetch + reset --mixed"]
        Handoff -.->|Updates metadata| LocalGit[".git Folder inside Vault"]
    end

Model A: Standalone Vault (Recommended for 99% of Users)

  • Structure: Your Obsidian vault folder is a pure directory containing notes and configuration—it does not contain a .git/ directory.
  • How it works: Both your mobile device and your desktop computer use Vault Relay to communicate directly with GitHub over HTTPS.
  • Benefits:
    • Zero Git debt or desynchronization: Because there is no native Git repository inside the vault, there is no possibility of spurious "unstaged changes", branch divergence, or missing commit objects.
    • Seamless cross-platform experience: Operates identically and cleanly on Windows, macOS, Linux, iOS, and Android.
    • Zero shell or external dependencies: Completely sandbox-safe; requires no Git binary installation, terminal commands, or background daemons on any device.
  • Need a local Git repository for external automation, scripts, or backups? Simply git clone your GitHub repository into a separate dedicated directory on your computer (e.g., ~/Developer/my-vault-repo/ or D:\GitHub\notes-repo\). When you want to inspect history or run scripts, just run git pull in that directory. The two locations remain completely isolated and will never interfere with each other.

Model B: Colocated Vault & Native Git Repository (Advanced / Optional)

  • Structure: You opened Obsidian directly inside a folder that was cloned via native git clone (contains a .git/ directory at the vault root).
  • Why divergence occurs: When Vault Relay pushes or pulls commits through GitHub's HTTPS API, files in your vault are updated, but your local .git metadata remains at the older commit until a local fetch occurs. Native git status may report unstaged changes.
  • Solution: Vault Relay provides an optional Desktop setting (Desktop Git integration) that writes a declarative signal file (.obsidian/github-vault-relay/git-handoff.json). Companion helper scripts (scripts/git-handoff.ps1 for Windows, scripts/git-handoff.sh for macOS/Linux) can consume this signal to run git fetch origin <branch> --quiet and git reset --mixed <remoteCommitSha>, bringing local Git metadata in sync without re-downloading working files or compromising Obsidian's sandbox security.

Installation

For a beta or mobile install, use BRAT with this repository URL:

https://github.com/ankhang0704/github-vault-relay

For a manual install, copy main.js, manifest.json, and styles.css from the release into <vault-config-dir>/plugins/github-vault-relay/, then reload and enable the plugin. <vault-config-dir> is normally .obsidian, but the runtime configuration directory is not assumed to have that name.

Token setup

Use a GitHub fine-grained PAT scoped to the single repository. The required repository permission is Contents: Read and write; GitHub may add read-only Metadata automatically.

Vault Relay stores the active token only through Obsidian SecretStorage under github-vault-relay-pat. Plugin data.json and localStorage are not runtime token stores. Legacy token locations are read only for one-time migration when secure storage is available, then purged after verification. Clearing a token requires explicit confirmation.

Sync model

The classifier compares three inputs: local vault files, the remote Git tree, and the durable state.json baseline. The ten file states are:

State Meaning Normal handling
LOCAL_ONLY Local file exists without remote file or baseline Candidate for push/create
REMOTE_ONLY Remote file exists without local file or baseline Candidate for pull/create
LOCAL_CHANGED Local SHA differs from baseline; remote still matches baseline Candidate for push/update
REMOTE_CHANGED Remote SHA differs from baseline; local still matches baseline Candidate for pull/update
POTENTIAL_CONFLICT Both sides diverged from the baseline Preserve and request review
UNCHANGED Local and remote canonical SHAs match No-op
LOCAL_DELETED Baseline file is absent locally but unchanged remotely Candidate to delete from Git tree
REMOTE_DELETED Baseline file is absent remotely but unchanged locally Candidate to remove locally
DELETE_CONFLICT One side deleted while the other side modified Preserve and request explicit resolution
DELETED Baseline file is absent on both sides Prune obsolete baseline

OVERSIZED and UNSAFE are scan counters/guards, not additional classifier states.

Pull

Safe Pull fetches the remote ref/tree, downloads blobs, verifies raw Git SHA-1 integrity, canonicalizes .md, .txt, and .canvas line endings to LF, and keeps other bytes unchanged. It records recovery evidence before local writes, verifies the result, then advances state.json. A remote deletion uses Obsidian's app.fileManager.trashFile() after its baseline proof and recovery snapshot are in place.

Push

Safe Push reads local bytes, creates Git blobs, constructs a tree from the remote base tree, creates one commit, revalidates local bytes, and updates the branch ref with force: false. It then reads the authoritative ref/tree again. The local baseline advances only after remote verification succeeds. If the PATCH response is ambiguous, the client checks the authoritative ref before deciding whether the commit landed.

Unified Sync is not a transaction

Pull and Push are sequential operations. If Pull succeeds and a later Push fails, the successful Pull is retained; the plugin does not pretend it can roll back a distributed GitHub operation.

Storage and path semantics

Plugin-private state is stored under:

${app.vault.configDir}/github-vault-relay/

For a default vault this is commonly .obsidian/github-vault-relay/, but .obsidian is only an example. The directory contains state.json, conflicts_meta.json, conflicts/, pull-recovery/, and delete-recovery/ as needed. Root _vault-relay/ is user content in the current model and is not plugin-owned.

The source computes both the canonical storage path and the live configuration-directory exclusion from app.vault.configDir. Persisted/user rules are retained, while fresh settings, parsed rules, migrations, local scans, remote filtering, and sync engine constructors all ensure the live config directory cannot be synchronized.

File, Git, and safety boundaries

  • Text canonicalization is limited to .md, .txt, and .canvas.
  • Binary files are transferred as bytes and validated by Git blob SHA.
  • Git tracks files, not empty directories.
  • An existing Git repository/branch is required; an unborn repository cannot be manipulated through the implemented Git Data API flow.
  • The canonical empty root tree is 4b825dc642cb6eb9a060e54bf8d69288fbee4904 when the synchronized result contains zero files.
  • Remote writes use Git Data API blobs, trees, commits, and refs. The plugin does not call GitHub DELETE endpoints or PUT /contents.
  • All mutation operations are guarded by an in-memory MutationCoordinator lease within the Obsidian app instance.

Network and privacy

The plugin talks directly to https://api.github.com when settings are configured or a user-triggered sync/connection action runs. It has no relay server, analytics, telemetry, or crash-reporting service.

Vault Relay enumerates vault paths and reads allowed file bytes to compare local content with the selected GitHub repository. Vault API enumeration is supplemented by Obsidian's DataAdapter for user dot-folders such as .agents/ and .vscode/; it does not use Node/Electron filesystem APIs. The live app.vault.configDir, .git/, .trash/, and _fit/ remain explicitly excluded, while user _vault-relay/ content remains syncable. Allowed paths and contents are sent to the selected GitHub repository during sync. Do not put secrets in notes unless you intend to store them in that repository.

PAT redaction is implemented by src/security/redact.ts and used by GitHub, storage, sync, and UI error paths. Production diagnostics pass caught errors through the sanitizer; focused closure tests also guard against direct caught-error logging.

Documentation

  • Project Source of Truth
  • Engineering Notes
  • System Architecture
  • Manual Test Matrix
  • Security Policy
  • Contributing
  • Changelog
  • Documentation index

License

MIT. See LICENSE.

HealthExcellent
ReviewPassed
About
Sync Obsidian Mobile and Desktop vaults with a GitHub repository via GitHub's REST and Git Data APIs over HTTPS, without installing Git or running background daemons. Perform safe unified syncs that pull eligible remote changes then push eligible local edits as single Git commits, preserve moves and deletions, handle empty-root trees, and halt on ambiguous state to protect data.
GitSyncingIntegrations
Details
Current version
1.0.8
Last updated
3 days ago
Created
Last week
Updates
17 releases
Downloads
49
Compatible with
Obsidian 1.11.4+
Platforms
Desktop, Mobile
License
MIT
Report bugRequest featureReport plugin
Author
Nguyễn An KhangNguyễn An Khangankhang0704
GitHubankhang0704
  1. Community
  2. Plugins
  3. Git
  4. GitHub Vault Relay

Related plugins

Fast Note Sync

Real-time sync of your vaults across server, mobile, and web; shareable with anyone; supports REST and MCP integrations to build your personal AI knowledge base.

Self-hosted LiveSync

Sync vaults securely to self-hosted servers or WEBRTC.

Google Drive Sync

Syncs a vault into Google Drive for cross-platform use (works for iOS).

Sync Engine

The extensible vault synchronization engine: Fast · Free · Reliable. Supports WebDAV, S3, and Google Drive.

Nutstore Sync

Sync your vault with Nutstore (坚果云) using WebDAV protocol.

OneDrive Sync

Sync your Obsidian vault with OneDrive Personal/Consumer

GitHub

GitHub Sync

Sync vault to personal GitHub.

Remotely Save

Sync notes between local and cloud with smart conflict: S3, Dropbox, webdav, OneDrive, Google Drive, Box, pCloud, Yandex Disk, Koofr, Azure Blob Storage.

Air Sync

Sync your vault with cloud storage (Google Drive, OneDrive, Dropbox).

BRAT

Easily install a beta version of a plugin for testing.