Created
August 3, 2026 10:32
-
-
Save romancone/abbad712051c6ab80fb329381945d740 to your computer and use it in GitHub Desktop.
Migrating Claude Code Desktop Sessions Between Macs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Migrating Claude Code Desktop Sessions Between Macs | |
| Two things need to travel together when you move Claude Code (desktop app) history to a new Mac: | |
| 1. **Session transcripts** — `~/.claude/projects/**/*.jsonl` — the real conversation content. | |
| 2. **Session registry entries** — `~/Library/Application Support/Claude/claude-code-sessions/$ACCOUNT_ID/**/local_*.json` — small descriptor files the desktop app's **Code** tab actually reads to know a session exists. | |
| The transcript alone is **not enough** — without a matching registry entry, the Code tab won't show the session, even though the conversation data is fully intact on disk. | |
| ## Variables used below | |
| | Variable | Meaning | | |
| |---|---| | |
| | `$USER` | your macOS username | | |
| | `$ACCOUNT_ID` | your Claude account UUID — find it by running `ls "$HOME/Library/Application Support/Claude/claude-code-sessions"` | | |
| | `$BACKUP_DIR` | a staging folder for the backup, e.g. `/Users/$USER/claude-backup` | | |
| If you have multiple accounts/workspaces on one machine, only touch the `$ACCOUNT_ID` folder(s) you actually want to migrate — leave any others alone. | |
| --- | |
| ## 1. Backup on the source Mac (zsh) | |
| ```zsh | |
| BACKUP_DIR="/Users/$USER/claude-backup" | |
| ACCOUNT_ID="<your-account-uuid>" # from: ls "$HOME/Library/Application Support/Claude/claude-code-sessions" | |
| mkdir -p "$BACKUP_DIR" | |
| # CLI session transcripts + settings | |
| mkdir -p "$BACKUP_DIR/.claude" | |
| rsync -a "$HOME/.claude/" "$BACKUP_DIR/.claude/" | |
| cp "$HOME/.claude.json" "$BACKUP_DIR/.claude.json" | |
| # Desktop app's session registry — only YOUR account | |
| mkdir -p "$BACKUP_DIR/Library/Application Support/Claude/claude-code-sessions" | |
| rsync -a \ | |
| "$HOME/Library/Application Support/Claude/claude-code-sessions/$ACCOUNT_ID/" \ | |
| "$BACKUP_DIR/Library/Application Support/Claude/claude-code-sessions/$ACCOUNT_ID/" | |
| ``` | |
| Move `$BACKUP_DIR` to the new Mac however you like (external drive, `scp`, AirDrop, cloud sync, etc.). | |
| --- | |
| ## 2. Merge on the new Mac (zsh) | |
| **Key rule: merge, don't overwrite.** The new Mac likely already has its own active session with its own registry file — never clobber existing files, only add the ones that are missing. | |
| ```zsh | |
| BACKUP_DIR="/Users/$USER/claude-backup" | |
| ACCOUNT_ID="<your-account-uuid>" | |
| # 2a. Merge CLI session transcripts (skip anything that already exists) | |
| rsync -a --ignore-existing \ | |
| "$BACKUP_DIR/.claude/projects/" \ | |
| "$HOME/.claude/projects/" | |
| # 2b. Merge the desktop app's registry entries for your account (skip existing) | |
| SRC="$BACKUP_DIR/Library/Application Support/Claude/claude-code-sessions/$ACCOUNT_ID" | |
| DST="$HOME/Library/Application Support/Claude/claude-code-sessions/$ACCOUNT_ID" | |
| find "$SRC" -name "local_*.json" | while read -r src_file; do | |
| session_dir=$(basename "$(dirname "$src_file")") | |
| base=$(basename "$src_file") | |
| mkdir -p "$DST/$session_dir" | |
| if [ -e "$DST/$session_dir/$base" ]; then | |
| echo "skip (already exists): $session_dir/$base" | |
| else | |
| cp -n "$src_file" "$DST/$session_dir/$base" | |
| echo "merged: $session_dir/$base" | |
| fi | |
| done | |
| ``` | |
| **Fully quit and relaunch** the Claude desktop app afterwards (not just a window reload) — the Code tab only picks up new registry entries on a cold start. | |
| --- | |
| ## 3. Clean up the source Mac (zsh) | |
| Only run this **after confirming** the sessions appear correctly on the new Mac — it permanently removes the source copy. | |
| ```zsh | |
| ACCOUNT_ID="<your-account-uuid>" | |
| rm -rf "$HOME/Library/Application Support/Claude/claude-code-sessions/$ACCOUNT_ID" | |
| ``` | |
| If you also use "local agent mode" sessions, the same account has a sibling folder that can be cleaned up the same way: | |
| ```zsh | |
| rm -rf "$HOME/Library/Application Support/Claude/local-agent-mode-sessions/$ACCOUNT_ID" | |
| ``` | |
| --- | |
| ## Notes | |
| - Registry files (`local_*.json`) reference a `cliSessionId` that must match a `.jsonl` file under `~/.claude/projects/` — always migrate both together. | |
| - If a merged session still doesn't appear after a full app restart, double-check you copied the *entire* session's registry folder (not just some of its files) and that the corresponding `.jsonl` transcript is present too. | |
| - Keep separate Claude accounts on separate machines unless you specifically intend to consolidate them — don't merge another account's `$ACCOUNT_ID` folder into yours. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment