[FEATURE REQUEST] `direnv` support
I often use claude in a directory with a direnv setup, and let claude modify the configuration. However claude is not able to see the updated PATH and other environment variables when direnv is reloaded. It will even try to run direnv reload, and then wonder why the changes it made did not work.
Adding direnv support to claude would be great!
I stumbled across this same problem. I've used aider which just inherits the shell that it was executed from and it works perfectly.
However I was able to make claude code eventually work. The trick is that claude seems to use your login shell, which on my system was set to zsh. Once I added the proper direnv hook it started to work as expected.
I've got a pretty complicated setup using nix + direnv together and that fixed it. Hopefully this helps anyone until proper shell inheritance is added.
I'm using nix as well- what did your fix look like? Why did it have to end up being complicated?
I've got a pretty complicated setup using nix + direnv together and that fixed it.
Claude seems to run every command in a new shell, so environment variables don't carry over between commands. I tested this with !export FOO=bar and then !echo $FOO. I'm on a mac with zsh.
My workaround was to put this in ~/.zshenv (I still have the regular hook in ~/.zshrc), it seems to work OK but it's gross and I'd like a better way:
# also need mkdir -p ~/.config/direnv
# touch ~/.config/direnv/direnv.toml
# because there is a bug that causes DIRENV_LOG_FORMAT to be ignore if the config
# file does not exist
if command -v direnv >/dev/null; then
if [[ ! -z "$CLAUDECODE" ]]; then
eval "$(direnv hook zsh)"
eval "$(DIRENV_LOG_FORMAT= direnv export zsh)" # Need to trigger "hook" manually
fi
fi
another problem is when direnv is used in a subfolder (for example in a monorepo): Bash(cd subfolder && command-managed-by-direnv) => command-managed-by-direnv will not be found (this might be similar to #2632)
For those using bash, I needed to put the script in .bashrc
programs.bash = {
enable = true;
bashrcExtra = ''
if command -v direnv >/dev/null 2>&1; then
if [ -n "$CLAUDECODE" ]; then
eval "$(direnv hook bash)"
eval "$(DIRENV_LOG_FORMAT= direnv export bash)"
fi
fi
'';
};
Does $SHELL env var match the type of shell you're running?
Setting SHELL helped for claude & fish+direnv+flake setup.
I wish I wrote down claude-code version. Setting $SHELL does not work anymore.
Adding specifically direnv reloading support is poor design - this could be fixed more generally by allowing a hook to modify shell commands before they are executed (eg. to add environment reloading commands, but there are also quite a few other use cases - I'd also like to eg. filter stdout/stderr).
For this particular problem, another workaround is just to quit claude and do a claude --resume (assuming you have direnv shell integration set up).
This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.
symlinked in /etc/profile.d/claude-direnv.sh
if command -v direnv >/dev/null 2>&1; then
if [ -n "$CLAUDECODE" ]; then
eval "$(DIRENV_LOG_FORMAT= direnv export bash)"
fi
fi
works well enough for me now