My ~/.claude weighs 2.8 GB. The part I actually wrote (instructions, settings, skills) is under a megabyte. Everything else was written by Claude Code on my behalf, or by the machine about itself. Copying the whole directory to the new computer looks like the fast path and causes the most trouble: on macOS the login doesn't even travel (it lives in the Keychain), on Linux a token travels that you'd rather not carry around, the transcripts stay keyed to paths that no longer exist, and the machine identifier belongs to a different machine.
Measured before writing this:
$ du -sh ~/.claude ~/.claude/projects ~/.claude/plugins ~/.claude/file-history
2.8G /Users/juan.nunez/.claude
1.1G /Users/juan.nunez/.claude/projects
691M /Users/juan.nunez/.claude/plugins
70M /Users/juan.nunez/.claude/file-history
$ ls -la ~/.claude/CLAUDE.md ~/.claude/settings.json
-rw-r--r-- 1 juan.nunez staff 2386 Sep 3 11:18 /Users/juan.nunez/.claude/CLAUDE.md
-rw------- 1 juan.nunez staff 2515 Sep 11 21:40 /Users/juan.nunez/.claude/settings.json
The three layers of ~/.claude
Everything in that directory belongs to one of three layers, and each layer moves differently.
What you wrote. CLAUDE.md, settings.json, skills/, commands/, agents/, workflows/, keybindings.json, themes/, output-styles/, plus any script settings.json points at (a statusLine, a hook), statusline.sh in my case. Plain text, machine-independent, copies as is. One more piece belongs here even though it lives in ~/.claude.json rather than ~/.claude: your user-scope MCP servers, the ones you added with claude mcp add --scope user. If you're unsure which file holds what, this tip maps it out.
What Claude wrote for you. projects/ holds every transcript and each project's auto memory, history.jsonl holds every prompt you've typed, file-history/ holds the snapshots behind /rewind. All of it can move, with one condition: projects/ is keyed by the repo's absolute path, encoded into the directory name.
$ ls ~/.claude/projects | grep -- -code- | head -3
-Users-juan-nunez-code-ai-infra
-Users-juan-nunez-code-ai-plugins
-Users-juan-nunez-code-craft
If your username differs on the new machine, or your repos live under a different path, those sessions don't show up in the /resume picker or in --continue from the repo, and that repo's auto memory isn't loaded. claude --resume <id> still opens them from any directory (since v2.1.223), but you need to know the id.
What the machine wrote about itself. The login, which on macOS is a Keychain item rather than a file. ~/.claude.json, which beyond your MCP servers stores machineID, anonymousId, the trust decision for every folder you've approved (51 in my case) and feature caches. And plugins/, whose installed_plugins.json points at absolute paths on your current disk. None of this gets copied. It regenerates in a minute.
How to set it up
1. Pack the layer that is yours
cd ~ && tar czf claude-config.tgz \
.claude/CLAUDE.md .claude/settings.json .claude/statusline.sh \
.claude/skills .claude/commands .claude/agents .claude/workflows \
.claude/keybindings.json .claude/themes .claude/output-styles
tar warns about paths that don't exist and carries on. My archive came out at 9 KB. If your skills are symlinks into a repo, as mine are, tar stores the link rather than the content: clone the repo on the new machine and the links resolve again.
Before you close the list, check which files under ~/.claude your settings.json references and add them:
grep -o '~/.claude/[^"]*' ~/.claude/settings.json
Unpack on the target with tar xzf claude-config.tgz -C ~.
2. Log in, don't copy the login
On macOS the token lives in the Keychain under Claude Code-credentials, not in a file. On Linux and Windows it lives in ~/.claude/.credentials.json. The answer is the same on all three: on the new machine, run claude and /login. One minute in a browser against the risk of carrying a token around on an external drive.
3. Bring only your user-scope MCP servers
~/.claude.json is not copied whole. Extract the mcpServers block and merge it into the file Claude Code creates on the new machine:
# source machine
jq '{mcpServers}' ~/.claude.json > mcp-servers.json
# target machine, Claude Code closed, after step 2
jq -s '.[0] * .[1]' ~/.claude.json mcp-servers.json > /tmp/c.json && mv /tmp/c.json ~/.claude.json
I tested this with a clean CLAUDE_CONFIG_DIR and nothing but that block copied in:
$ claude mcp list
context7: https://mcp.context7.com/mcp (HTTP) - ✔ Connected
wmedia: https://wmedia.es/mcp/wmedia (HTTP) - ✔ Connected
frontendleap-changelog: https://frontendleap.com/mcp/changelog (HTTP) - ✔ Connected
That block carries the headers with your API keys. Treat it as a secret while it travels.
4. Reinstall plugins from your settings.json
Your settings.json already carries the full list: extraKnownMarketplaces says where each marketplace comes from and enabledPlugins says which plugins you have on. Two jq lines print it:
jq -r '.extraKnownMarketplaces | to_entries[] | .value.source.repo' ~/.claude/settings.json
jq -r '.enabledPlugins | keys[]' ~/.claude/settings.json
Then, for each line, on the new machine:
$ claude plugin marketplace add juanwmedia/craft
✔ Successfully added marketplace: craft (declared in user settings)
$ claude plugin install craft@craft
✔ Successfully installed plugin: craft@craft (scope: user)
The 691 MB under plugins/ stay on the old disk. Only the versions you use come back down.
5. Optional: bring your sessions
This only makes sense when each repo's absolute path is identical on both machines. If it is, copy the project directory you care about, not the whole of projects/:
scp -r ~/.claude/projects/-Users-juan-nunez-code-ai-infra new:~/.claude/projects/
With that in place, the /resume picker and that repo's auto memory show up on the new machine. If the path doesn't match, the transcript is still usable by id: from ~/code/ai-infra I ran claude -p --resume <id> against a session stored under a different path and it answered. What doesn't cross paths is the picker and the memory. history.jsonl can move under the same condition: every line carries its project path.
What to copy and what to leave
| Path | Copy | Why |
|---|---|---|
CLAUDE.md, settings.json, skills/, agents/, commands/ |
Yes | Your configuration, plain text |
~/.claude.json |
Only the mcpServers block |
The rest is machine identity and per-folder trust |
| Login | No, run /login |
Keychain on macOS, .credentials.json on Linux and Windows |
plugins/ |
No, reinstall | installed_plugins.json points at absolute paths on the old disk |
projects/<path>/ |
If the path matches | Transcripts and auto memory keyed by absolute path |
history.jsonl |
If the paths match | Every prompt is tied to its project |
file-history/, paste-cache/, debug/, session-env/ |
No | Checkpoints and caches for sessions you won't resume |
One detail that takes a few minutes the first time: if you ever launched Claude Code with CLAUDE_CONFIG_DIR=~/.claude while trying out separate profiles, you have a second ~/.claude/.claude.json inside the directory. Claude Code builds the path as $CLAUDE_CONFIG_DIR/.claude.json, so that file belongs to that profile, not to you. The one that matters is ~/.claude.json in your home.
If what you want is not to move files but to write down how your environment is put together, /team-onboarding generates that guide from your own sessions.
Official docs: The .claude directory and Authentication: credential management
Requirements
jqfor the two extracts; without it, copy themcpServersblock out of~/.claude.jsonby hand- Claude Code closed on the new machine while you edit
~/.claude.json