Skip to content

Instantly share code, notes, and snippets.

@romancone
Created August 3, 2026 10:32
Show Gist options
  • Select an option

  • Save romancone/abbad712051c6ab80fb329381945d740 to your computer and use it in GitHub Desktop.

Select an option

Save romancone/abbad712051c6ab80fb329381945d740 to your computer and use it in GitHub Desktop.
Migrating Claude Code Desktop Sessions Between Macs
# 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