Claude Code installation on Linux (Ubuntu 24.04) - kdaisho/Blog GitHub Wiki

That was quite the battle against the Nix symlink wall. Here is the summary of why it was failing and the final setup that actually worked.

The Conflict

The Issue: The official Claude Code installer tried to modify your .zshrc and .local/bin. The Nix Barrier: Because you manage your Ubuntu setup with Home Manager, your .zshrc is a read-only symlink. The installer couldn't "write" the PATH changes, and even if it could, Nix would have wiped them out on the next switch.

The Permission Error

npm tried to install Claude into the /nix/store (the default location for the Node package), which is globally read-only.

The Final Working Solution

We bypassed the brittle curl script and used a "Nix-friendly" global NPM setup.\

1. Created a Local NPM "Safe House"

We created a folder in your home directory where you have full permissions, avoiding the /nix/store entirely.

mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global

2. Modified home.nix

We updated your Home Manager configuration to make the changes permanent and reproducible.

Added sessionVariables: Set NPM_CONFIG_PREFIX = "/home/jaeger/.npm-global"; so npm always knows where to go.

Added sessionPath: Included "/home/jaeger/.npm-global/bin" so your shell can find the claude binary.

Added envExtra: In the programs.zsh block, we added . ~/.nix-profile/etc/profile.d/hm-session-vars.sh to ensure Zsh actually loads the Home Manager variables.

3. Installed Claude Code

With the permissions and paths set, the installation finally went through:

npm install -g @anthropic-ai/claude-code

Key Takeaways for Future Tools

Avoid curl | bash: These scripts almost always fail on Nix because they expect a mutable filesystem.

Use the absolute path: When using home.sessionPath, use /home/jaeger/... instead of ~/... to ensure Nix handles the string correctly.

Manual Bridge: If you update home.nix and don't want to restart your computer, run home-manager switch followed by exec zsh.