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)
Important: GitHub Sync is incompatible with end-to-end encryption. GitHub stores notes as readable Markdown files. If you have encryption enabled, you must disable it in Settings before enabling GitHub Sync.
Authentication
GitHub Sync uses secure Device Flow OAuth:
- Open Settings > GitHub Sync
- Click “Connect GitHub”
- Visit the URL shown and enter the code
- Authorize Strayfiles in your browser
- 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
| Operation | Description |
|---|---|
| Clone | Initial setup, clones repo to local mirror |
| Pull | Fetch remote changes, detect conflicts |
| Push | Commit and push local changes |
| Sync | Full 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.jsonconflicts auto-resolved when Stray Cloud enabled
When both you and another device edit the same note:
- Strayfiles detects the conflict
- Shows base, local, and remote versions
- Choose: Keep Local, Keep Remote, or Auto-Merge
- 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:
| Feature | Protection |
|---|---|
| SSRF protection | Only github.com allowed as remote |
| Credential isolation | Uses ephemeral GIT_ASKPASS scripts |
| No embedded credentials | Tokens never in command line or history |
| Path validation | Prevents traversal attacks in tree.json |
| Command timeouts | 5 min clone, 2 min pull/push |
Retry Logic
Network failures are handled gracefully:
- Exponential backoff with jitter
- Rate limit handling with
retry-afterheaders - Configurable retry attempts (default: 5)
- Failed syncs queued for next attempt
Settings
Configure GitHub Sync in Settings > GitHub:
| Setting | Description |
|---|---|
| Enabled | Enable/disable GitHub sync |
| Repository | Owner/name of connected repo |
| Branch | Branch to sync (default: main) |
| Last Sync | Timestamp of last successful sync |
Deletion Behavior
When you delete a note, the action depends on how it was tracked:
| Origin | GitHub Action | Local Action |
|---|---|---|
| Created | Remove file | Delete file |
| Discovered | Remove file | Strip frontmatter |
| TomlConfig | Remove file | Remove from TOML |
GitHub Sync vs Git Sync (Free)
| Feature | GitHub Sync (Pro) | Git Sync (Free) |
|---|---|---|
| Authentication | Secure Device Flow OAuth | Your existing Git credentials |
| Repository | Dedicated notes repo | Any Git repo |
| Dual-sync | Yes, with Stray Cloud | No |
| Conflict resolution | Built-in 3-way merge | Use Git tools |
| iOS visibility | Yes | No |
| tree.json manifest | Yes | No |
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
- Subscribe to Pro or activate your existing subscription
- Open Settings > GitHub Sync
- Connect GitHub using Device Flow
- Create or select a private repository
- Start syncing - your notes are now backed up to GitHub