Encrypted with age • R2 / S3 / GCS supported
Quick Start • Setup Guide • Commands • Auto-Sync • Security
- Cross-device sync: Continue Claude Code conversations on any laptop
- Multi-provider storage: Cloudflare R2, AWS S3, or Google Cloud Storage
- End-to-end encryption: All files encrypted with age before upload
- Passphrase-based keys: Same passphrase = same key on any device (no file copying)
- Interactive wizard: Arrow-key driven setup with validation
- Self-updating:
claude-sync updateto get the latest version - Simple CLI:
push,pull,status,diff,conflictscommands - Compression: Gzip compression before encryption for faster syncs
- Auto-sync hooks: Optional Claude Code hooks for automatic push/pull
# Install
npm install -g @tawandotorg/claude-sync
# Set up (interactive wizard)
claude-sync init
# Push your sessions
claude-sync push# Install
npm install -g @tawandotorg/claude-sync
# Set up with SAME storage credentials
claude-sync init
# Select same provider (R2/S3/GCS)
# Enter same bucket name and credentials
# Choose "Passphrase" for encryption
# Enter the SAME passphrase as first device
# ✓ Encryption key verified <-- confirms passphrase matches!
# Preview what would be synced
claude-sync pull --dry-run
# Pull sessions (creates backup if you have existing files)
claude-sync pullSame passphrase = same encryption key. The init verifies your passphrase can decrypt remote files before completing.
| Provider | Free Tier | Best For |
|---|---|---|
| Cloudflare R2 | 10GB storage | Personal use (recommended) |
| AWS S3 | 5GB (12 months) | AWS users |
| Google Cloud Storage | 5GB | GCP users |
Cloudflare R2 (recommended)
- Go to Cloudflare Dashboard → R2 Object Storage
- Click "Create bucket" → name it
claude-sync - Go to "Manage R2 API Tokens" → "Create API Token"
- Select Object Read & Write permission → Create
You'll need: Account ID, Access Key ID, Secret Access Key
AWS S3
- Go to S3 Console → Create bucket
- Go to IAM Security Credentials
- Create Access Keys
You'll need: Access Key ID, Secret Access Key, Region
Google Cloud Storage
- Go to Cloud Storage → Create bucket
- Go to Service Accounts → Create service account
- Grant "Storage Object Admin" role → Create JSON key
You'll need: Project ID, Service Account JSON file (or use gcloud auth application-default login)
claude-sync initThe interactive wizard will guide you through:
- Select storage provider (R2, S3, or GCS)
- Enter credentials (provider-specific)
- Choose encryption method:
- Passphrase (recommended) - same passphrase on all devices = same key
- Random key - must copy
~/.claude-sync/age-key.txtto other devices
- Test the connection to verify everything works
# Upload local changes
claude-sync push
# Download remote changes
claude-sync pull| Path | Content |
|---|---|
~/.claude/projects/ |
Session files, auto-memory |
~/.claude/history.jsonl |
Command history |
~/.claude/agents/ |
Custom agents |
~/.claude/skills/ |
Custom skills |
~/.claude/plugins/ |
Plugins |
~/.claude/rules/ |
Custom rules |
~/.claude/settings.json |
Settings |
~/.claude/settings.local.json |
Local settings |
~/.claude/CLAUDE.md |
Global instructions |
Claude Code indexes project sessions by absolute filesystem path. This tool syncs ~/.claude/projects/ but does not perform path remapping, which means:
/Users/alice/Projects/my-app → ~/.claude/projects/-Users-alice-Projects-my-app/
/Users/bob/code/my-app → ~/.claude/projects/-Users-bob-code-my-app/
These are treated as completely different projects by Claude Code. After syncing, claude --resume on machine2 won't find sessions from machine1 if the project paths differ.
Workaround: Use consistent absolute paths across all devices. For example:
- Always clone repos to
~/Projects/on every machine - Use symlinks to maintain the same path structure
- Consider a standardized home directory structure
If you follow a consistent path convention, sessions will sync and resume correctly across devices.
claude-sync init # Set up configuration (interactive wizard)
claude-sync push # Upload local changes to cloud storage
claude-sync pull # Download remote changes from cloud storage
claude-sync status # Show pending local changes
claude-sync diff # Show differences between local and remote
claude-sync conflicts # List and resolve conflicts
claude-sync reset # Reset configuration (forgot passphrase)
claude-sync update # Update to latest version
claude-sync changelog # Show release history
claude-sync --help # Show all commandsclaude-sync pull # Normal pull (prompts if existing files)
claude-sync pull --dry-run # Preview what would change
claude-sync pull --force # Skip confirmation promptsclaude-sync init # Full setup wizard
claude-sync init --passphrase # Re-enter passphrase only (keeps storage config)
claude-sync init --force # Reset everything, start freshclaude-sync push -q # No output (for scripts)
claude-sync pull -qclaude-sync update --check # Check without installing
claude-sync update # Download and install latest versionclaude-sync changelog # Show recent releases
claude-sync changelog --limit 5 # Show last 5 releasesAutomatically sync when starting or exiting Claude Code sessions using built-in hooks.
claude-sync auto enable # Install auto-sync hooks into Claude Code
claude-sync auto disable # Remove auto-sync hooks
claude-sync auto status # Show current hook statusWhen enabled, hooks will:
- SessionStart: Pull latest changes from remote
- Stop: Push local changes to remote
Skip specific files or directories during sync by adding exclude patterns to your config (~/.claude-sync/config.yaml):
exclude:
- "*.tmp"
- "projects/*/node_modules/*"
- "projects/*/.git/*"Patterns use glob syntax and are matched against paths relative to ~/.claude.
Add to ~/.zshrc or ~/.bashrc:
# Auto-pull on shell start
if command -v claude-sync &> /dev/null; then
claude-sync pull -q &
fi
# Auto-push on shell exit
trap 'claude-sync push -q' EXITWhen you pull on a device that already has ~/.claude files, claude-sync will:
- Show what would change - files that would be overwritten, kept, or downloaded
- Ask for confirmation - choose to backup, overwrite, or abort
- Create a backup - saves existing files to
~/.claude.backup.{timestamp}
# Preview first
claude-sync pull --dry-run
# Pull with prompts
claude-sync pull
# Skip prompts (for scripts)
claude-sync pull --forceWhen both local and remote files change, the remote version is saved as .conflict:
claude-sync conflicts # Interactive resolution
claude-sync conflicts --list # Just list conflicts
claude-sync conflicts --keep local # Keep all local versions
claude-sync conflicts --keep remote # Keep all remote versionsInteractive options:
- [l] Keep local (delete conflict file)
- [r] Keep remote (replace local)
- [d] Show diff
- [s] Skip
- [q] Quit
If you entered the wrong passphrase on a new device:
# Re-enter passphrase (keeps your storage config)
claude-sync init --passphraseThe init will verify your passphrase can decrypt remote files before completing.
The passphrase is never stored. If you forget it:
- Your encrypted files cannot be recovered
- Reset and start fresh:
claude-sync reset --remote # Delete remote files and local config
claude-sync init # Set up again with new passphrase
claude-sync push # Re-upload from this device- Files compressed with gzip, then encrypted with age before upload
- Passphrase-derived keys use Argon2 (memory-hard KDF)
- Passphrase is never stored - only the derived key at
~/.claude-sync/age-key.txt - Cloud storage is private (API key/IAM auth)
- Config files stored with 0600 permissions
- Backward compatible: can read both compressed and uncompressed remote files
Claude sessions typically use < 50MB. Syncing is effectively free on any provider:
| Provider | Free Tier |
|---|---|
| Cloudflare R2 | 10GB storage, 1M writes, 10M reads/month |
| AWS S3 | 5GB for 12 months (then ~$0.023/GB) |
| Google Cloud Storage | 5GB, 5K writes, 50K reads/month |
Prerequisite: Node.js 14+ (no Go required - downloads pre-compiled binary)
# Global install
npm install -g @tawandotorg/claude-sync
# Or one-time use
npx @tawandotorg/claude-sync initPrerequisite: Node.js 14+
# Add to ~/.npmrc
echo "@tawanorg:registry=https://npm.pkg.github.com" >> ~/.npmrc
# Install
npm install -g @tawanorg/claude-syncPrerequisite: None
# macOS ARM (M1/M2/M3)
curl -L https://github.com/tawanorg/claude-sync/releases/latest/download/claude-sync-darwin-arm64 -o claude-sync
chmod +x claude-sync
sudo mv claude-sync /usr/local/bin/See GitHub Releases for all platforms.
Prerequisite: Go 1.21+ (for developers)
go install github.com/tawanorg/claude-sync/cmd/claude-sync@latestPrerequisite: Go 1.21+
git clone https://github.com/tawanorg/claude-sync
cd claude-sync
make build
./bin/claude-sync --versionmake test # Run tests
make fmt # Format code
make check # Run all pre-commit checks
make build-all # Build for all platforms
make setup-hooks # Enable git pre-commit hooksMIT
