Back to catalogue
WorkflowCwdChangedCwdChangedWhen working directory changes· non-blocking
Reload direnv on directory change
Bash always runs in the right env per folder
Automatically reloads environment variables via direnv when Claude changes its working directory, ensuring Bash commands use the right environment for the current directory.
What does the Reload direnv on directory change hook do?
Reload direnv on directory change is a Claude Code CwdChanged hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Bash always runs in the right env per folder.
Use cases
- Mono-repo projects with different environments per subfolder
- Automatic .envrc management with direnv
- Sync CLAUDE_ENV_FILE with the current directory's environment
Tags
#direnv#environment#cwd#monorepo
settings.json fragment
{
"hooks": {
"CwdChanged": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/reload-direnv.mjs",
"type": "command"
}
],
"matcher": ""
}
],
"SessionStart": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/reload-direnv.mjs",
"type": "command"
}
],
"matcher": ""
}
]
}
}Script · .claude/hooks/reload-direnv.mjs
#!/usr/bin/env node
// Recharge direnv quand le répertoire de travail change (CwdChanged)
import { readFileSync, existsSync } from 'fs';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
function defaultExec(cmd, cwd) {
execSync(cmd, { cwd, stdio: 'ignore', timeout: 5_000 });
}
export function run(input, { exec = defaultExec, exists = existsSync } = {}) {
const newCwd = input.cwd ?? input.new_cwd ?? process.cwd();
const envrc = `${newCwd}/.envrc`;
if (!exists(envrc)) return null;
try {
exec('direnv allow .', newCwd);
return { message: `[reload-direnv] direnv rechargé dans ${newCwd}\n` };
} catch {
// direnv absent — non bloquant
return null;
}
}
/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, 'utf8'));
const result = run(input);
if (result?.message) process.stderr.write(result.message);
}