Back to catalogue
ValidationPostToolUse· Write|EditPostToolUseAfter tool execution · non-blocking· non-blocking
Biome lint after write
Lint errors fixed in the same loop, not in CI
Runs Biome on the file just written and returns the errors to the agent so it fixes them immediately within the same loop.
What does the Biome lint after write hook do?
Biome lint after write is a Claude Code PostToolUse hook matching Write|Edit. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Lint errors fixed in the same loop, not in CI.
As a PostToolUse 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
- Continuous quality
- Auto-fix loop
- Lint standards
Tags
#validation#biome#lint#quality
settings.json fragment
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/biome-check.mjs",
"type": "command"
}
],
"matcher": "Write|Edit"
}
]
}
}Script · .claude/hooks/biome-check.mjs
#!/usr/bin/env node
// @hookstack post-write-biome
// Vérifie le fichier avec Biome après écriture (PostToolUse Write|Edit)
import { readFileSync } from 'fs';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
function defaultExec(cmd) {
return execSync(cmd, { stdio: 'pipe', timeout: 15_000 });
}
export function run(input, { exec = defaultExec } = {}) {
const filePath = input.tool_input?.file_path ?? '';
if (!filePath || !/\.[cm]?[jt]sx?$/.test(filePath)) return null;
try {
exec(`npx --no-install biome lint --error-on-warnings "${filePath}"`);
return null;
} catch (err) {
const output = err.stdout?.toString() ?? '';
return output ? { message: `Biome: ${output.trim()}\n` } : 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);
}