Back to docs
pro

GitHub Sync

Sync Notes to GitHub

GitHub Sync is a Pro add-on that backs up your notes to a private GitHub repository. Get version control, backup, and portability alongside Stray Cloud.

Overview

  • Paid add-on: Works standalone or alongside Stray Cloud
  • Dual-sync support: Use both Supabase and GitHub simultaneously
  • Private repos only: Safety check ensures repository privacy
  • iOS transparency: iOS devices see GitHub sync status (read-only)

Authentication

GitHub Sync uses secure Device Flow OAuth:

  1. Open Settings > GitHub Sync
  2. Click “Connect GitHub”
  3. Visit the URL shown and enter the code
  4. Authorize Strayfiles in your browser
  5. Return to Strayfiles - you’re connected

No GitHub tokens stored in plaintext. Tokens are validated on startup with automatic expiration detection.

Repository Structure

Your notes are organized in a clean structure:

your-notes-repo/
├── .strayfiles/
│   └── tree.json       # Directory structure manifest
├── notes/
│   ├── note-uuid-1.md  # Individual notes
│   └── note-uuid-2.md
└── README.md           # Auto-generated

The tree.json manifest preserves your folder structure and metadata.

Sync Operations

OperationDescription
CloneInitial setup, clones repo to local mirror
PullFetch remote changes, detect conflicts
PushCommit and push local changes
SyncFull pull → resolve → push cycle

Conflict Detection

GitHub Sync uses content-hash based conflict detection (SHA-256):

  • Same 3-way merge as Stray Cloud conflicts
  • Unified conflict resolution UI
  • tree.json conflicts auto-resolved when Stray Cloud enabled

When both you and another device edit the same note:

  1. Strayfiles detects the conflict
  2. Shows base, local, and remote versions
  3. Choose: Keep Local, Keep Remote, or Auto-Merge
  4. Resolution synced to all backends

Dual-Sync with Stray Cloud

When both Stray Cloud and GitHub are enabled:

Edit → Stray Cloud (realtime) → GitHub (batch)
  • Stray Cloud handles real-time sync between devices
  • GitHub sync runs periodically or on demand
  • Sync guard prevents echo loops

This gives you the best of both worlds: instant sync plus version-controlled backup.

Excluding Notes from GitHub

To keep specific notes local-only, add sync: false to frontmatter:

---
strayfiles:
  enabled: true
  sync: false
---

Notes with sync: false won’t sync to GitHub (or Stray Cloud).

iOS Transparency

iOS devices cannot perform GitHub sync directly (no filesystem access), but they see:

  • “Synced to GitHub” status on notes
  • Last sync timestamp
  • Current branch (if not main)
  • Warnings if synced branch differs

Security

GitHub Sync is built with security in mind:

FeatureProtection
SSRF protectionOnly github.com allowed as remote
Credential isolationUses ephemeral GIT_ASKPASS scripts
No embedded credentialsTokens never in command line or history
Path validationPrevents traversal attacks in tree.json
Command timeouts5 min clone, 2 min pull/push

Retry Logic

Network failures are handled gracefully:

  • Exponential backoff with jitter
  • Rate limit handling with retry-after headers
  • Configurable retry attempts (default: 5)
  • Failed syncs queued for next attempt

Settings

Configure GitHub Sync in Settings > GitHub:

SettingDescription
EnabledEnable/disable GitHub sync
RepositoryOwner/name of connected repo
BranchBranch to sync (default: main)
Last SyncTimestamp of last successful sync

Deletion Behavior

When you delete a note, the action depends on how it was tracked:

OriginGitHub ActionLocal Action
CreatedRemove fileDelete file
DiscoveredRemove fileStrip frontmatter
TomlConfigRemove fileRemove from TOML

GitHub Sync vs Git Sync (Free)

FeatureGitHub Sync (Pro)Git Sync (Free)
AuthenticationSecure Device Flow OAuthYour existing Git credentials
RepositoryDedicated notes repoAny Git repo
Dual-syncYes, with Stray CloudNo
Conflict resolutionBuilt-in 3-way mergeUse Git tools
iOS visibilityYesNo
tree.json manifestYesNo

Use GitHub Sync (Pro) for dedicated notes backup with full Strayfiles integration.

Use Git Sync (Free) for notes that live in existing code repositories.

Troubleshooting

“Token expired”: Re-authenticate in Settings > GitHub > Reconnect.

“Push rejected”: Another device may have pushed. Trigger a manual sync to pull first.

“Private repository required”: GitHub Sync only works with private repos for security. Make your repo private or create a new one.

“Sync taking too long”: Large repos may take time on first clone. Subsequent syncs are incremental.

Getting Started

  1. Subscribe to Pro or activate your existing subscription
  2. Open Settings > GitHub Sync
  3. Connect GitHub using Device Flow
  4. Create or select a private repository
  5. Start syncing - your notes are now backed up to GitHub