Back to catalogue
WorkflowSessionStart
Dependency check and install at startup
Open a session, environment's already ready
Checks for the required system tools and automatically installs the project dependencies (npm ci, uv sync) at session startup.
What does the Dependency check and install at startup hook do?
Dependency check and install at startup is a Claude Code SessionStart hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Open a session, environment's already ready.
As a SessionStart hook it runs after the action, reacting to what just happened rather than blocking it. Because it is a deterministic Node.js script, it executes on every matching event without relying on the model to remember — the guarantee that makes agentic workflows safe to automate.
Use cases
- Environment always ready as soon as a session opens
- Automatic onboarding on a new project
Tags
#setup#dependencies#onboarding#npm#uv#install
settings.json fragment
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/setup-check-deps.mjs",
"type": "command"
}
],
"matcher": ""
}
]
}
}Script · .claude/hooks/setup-check-deps.mjs
#!/usr/bin/env node
// @hookstack setup-check-install-deps
// Vérifie que les dépendances du projet sont à jour au démarrage de session (SessionStart)
import { existsSync, statSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
const SPECS = [
["pnpm-lock.yaml", "node_modules", "pnpm install"],
["package-lock.json", "node_modules", "npm ci"],
["yarn.lock", "node_modules", "yarn install --frozen-lockfile"],
["requirements.txt", ".venv", "pip install -r requirements.txt"],
];
export function run({
exists = existsSync,
stat = statSync,
projectDir = process.env.CLAUDE_PROJECT_DIR ?? process.cwd(),
} = {}) {
const warnings = [];
for (const [lockfile, modulesDir, installCmd] of SPECS) {
const lock = join(projectDir, lockfile);
const mods = join(projectDir, modulesDir);
if (!exists(lock)) continue;
if (!exists(mods)) {
warnings.push(
`[setup-check-deps] ⚠ ${modulesDir} absent — lancez : ${installCmd}\n`,
);
continue;
}
if (stat(lock).mtimeMs > stat(mods).mtimeMs) {
warnings.push(
`[setup-check-deps] ⚠ ${lockfile} plus récent que ${modulesDir} — lancez : ${installCmd}\n`,
);
}
}
return { warnings, message: warnings.join("") };
}
/* v8 ignore next 4 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const result = run();
if (result.message) process.stderr.write(result.message);
}