How to Sync Claude Code Config Across Multiple Macs with Syncthing

How to Sync Claude Code Config Across Multiple Macs with Syncthing

I use a MacBook Pro and a Mac Mini side by side. Both run Claude Code, but custom skills, agents, and memory files created on one machine don't exist on the other. Manually copying them every time is not an option.

I wanted to automatically sync the ~/.claude folder between the two machines while also tracking changes with Git.

What's inside ~/.claude

All Claude Code configuration lives in ~/.claude/.

PathDescriptionSync needed
CLAUDE.mdGlobal instructionsYes
settings.jsonSettings (hooks, MCP, permissions)Yes
memory/Global memoryYes
skills/Custom skillsYes
agents/Custom agentsYes
commands/Custom slash commandsYes
projects/*/memory/Per-project memoryYes
*.jsonlSession logs (~1.6GB)No
cache/, debug/, etc.Cache, temp filesNo
settings.local.jsonMachine-specific settingsNo
.credentials.jsonAuth credentialsNo

In my case, the entire folder was about 2GB, but only ~165MB actually needed syncing. The rest was session logs and cache.

Why not sync sessions

Session logs (*.jsonl) and session data (UUID folders) are excluded from sync. The volume keeps growing, and I start and end dozens of sessions a day. There is no need to sync all of that. My workflow is already split: short-lived sessions run on the MacBook, long-running sessions run on the Mac Mini. And I certainly did not want my conversation history pushed to GitHub.

Comparing sync options

Dropbox

Cloud-based sync. Automatic and stable. But you'd need to move ~/.claude into the Dropbox folder and create a symlink. This breaks Git version control since the symlink gets committed instead of the actual files. Free plan is limited to 3 devices. Idles at 200-400MB RAM.

rsync

One-directional copy tool. You can automate it with cron, but bidirectional sync and conflict resolution need to be built from scratch. Essentially manual.

Syncthing

P2P real-time bidirectional sync. Open source (70k+ GitHub stars). No limits on devices, storage, or bandwidth. Idles at 30-50MB RAM. Syncs ~/.claude in place, so you can use Git in the same directory. No symlinks needed.

Why Syncthing: free, lightweight, syncs the original folder without symlinks, making it fully compatible with Git version control.

Setup

1. Install and start

On both machines:

brew install syncthing
brew services start syncthing

Access the WebUI at http://localhost:8384.

2. Connect the two machines

  1. On Machine A's WebUI, go to Actions > Show ID and copy the Device ID
  2. On Machine B's WebUI, click Add Remote Device and paste the ID
  3. Accept the connection request on Machine A

Adding from one side establishes a bidirectional connection.

3. Configure the shared folder

On Machine A, click Add Folder:

  • Folder Label: claude-config
  • Folder Path: ~/.claude
  • Folder ID: claude-config

Save, then Edit > Sharing tab > check the other machine. Accept the share request on Machine B.

4. Set up .stignore

~/.claude/.stignore:

// Session logs
*.jsonl

// Session data (UUID folders)
projects/*/????????-????-????-????-????????????
projects/*/????????-????-????-????-????????????.jsonl

// Projects that don't need memory/skill sync
projects/-Users-sh

// Cache and temp
cache/
debug/
file-history/
paste-cache/
session-env/
shell-snapshots/
sessions/
telemetry/
tasks/
downloads/
ide/
backups/
plans/

// Machine-specific
settings.local.json
.credentials.json

// System
.DS_Store

// Git
.git/

I occasionally run Claude Code from my home directory (~), which creates a project folder under projects/ based on the home path. For example, if your username is sh, it creates projects/-Users-sh. I use this for quick, throwaway sessions, so there's no need to sync memory or skills for it. I excluded the entire project path.

Note: Syncthing's .stignore does not support character ranges like [0-9a-f]. Use ? wildcards for UUID patterns instead.

5. Add Git version control

Initialize Git in the same ~/.claude folder. The .gitignore is nearly identical to .stignore, with the addition of Syncthing metadata (.stfolder/, .stversions/).

cd ~/.claude
git init
gh repo create .claude --private --source=. --push

Skills that contain external git repos should be managed as submodules.

git submodule add https://github.com/garrytan/gstack.git skills/gstack

Gotchas

Never sync .credentials.json

I initially forgot to exclude .credentials.json. One machine's auth credentials overwrote the other's, and I got logged out. This file must be unique per machine. Exclude it from both .stignore and .gitignore.

.stignore glob syntax differs from .gitignore

.gitignore supports character ranges like [0-9a-f], but .stignore throws a parse error on them. Use ????????-????-????-????-???????????? for UUID folder patterns.

Skills may contain git repos

Some community skills are installed via git clone. Running git add on these triggers an "embedded git repo" warning. Register them as submodules, or exclude them in .gitignore.

Result

When I install a new skill or add a memory file on one machine, it shows up on the other within seconds. Git tracks the change history and backs everything up to GitHub.

Maintenance is minimal. Occasionally check the WebUI at localhost:8384. After macOS updates, verify Syncthing is running with brew services list.