Read-only Claude Code PostToolUse hook that runs Biome's formatter, linter, and import-sorting checks on edited JavaScript, TypeScript, JSON, CSS, and GraphQL files without auto-writing changes.
This hook runs `biome check` without `--write`, so it reports formatter, linter, and import-sorting diagnostics but does not modify files., Do not add `--write` or `--unsafe` until the team has reviewed the hook behavior, backup expectations, and failure mode for generated edits., The hook exits non-zero when Biome reports diagnostics. Depending on Claude Code settings, this can interrupt the current workflow until issues are reviewed., Use a project-pinned Biome package when possible. The script prefers `./node_modules/.bin/biome` and avoids network-install fallbacks., Keep matchers scoped to write/edit tools. Running Biome after every tool call can add noise and slow down large projects.
Privacy notes
Biome diagnostics can include file paths, rule names, code excerpts, import names, comments, and source snippets from edited files., Claude Code hook logs, terminal scrollback, screenshots, support tickets, and AI transcripts can retain Biome diagnostics outside the repository., Avoid pasting real customer code, private filenames, generated secrets, or proprietary source excerpts from hook output into public issue comments.
Author
oktofeesh1
Submitted by
oktofeesh1
Claim status
unclaimed
Last verified
2026-06-04
Decision playbook
Review trust signals before you adopt
Signals are present but mixed. Use the checklist below to confirm the source and operational safety for your environment.
Compare context
Selected
0
Current score
78
Baseline
—
Delta
No baseline selected
No major trust-signal divergence detected in the current selection.
Source and provenance checks
Complete
Confirm ownership and provenance before trusting install instructions.
Source link availableRequired
Open the canonical repository and verify ownership.
Done
Source provenance statusRequired
Marked as source-backed.
Done
Metadata reviewed
Registry metadata indicates a reviewed listing.
Done
Safety and privacy checks
Complete
Validate risk disclosures before installation or API wiring.
Safety notes presentRequired
Review the listed safety guidance before running commands.
Done
Privacy notes presentRequired
Review data handling notes before connecting accounts or secrets.
Done
Trust level risk gateRequired
Trust level does not block evaluation.
Done
Package and install checks
Needs review
Check package metadata and artifact integrity signals.
Install payload available
Install or copy payload is available for review.
Done
Package verification flag
No package verification flag provided.
Pending
Checksum metadata
No checksum provided for downloaded artifact.
Pending
Compare-driven decision checks
Needs review
Use compare context to validate trade-offs before adoption.
Compare tray has multiple entries
Add at least one more entry to compare trust differences.
Current risk score 16/100. Use staged verification before broader rollout.
Risk 16
Pre-adoption checks
Validate source and review signals before any execution.
Confirm source provenanceRequired
Source URL/provenance metadata is present.
Done
Confirm metadata review state
Listing has review metadata.
Done
Verify install payload
Install/config payload exists and can be inspected.
Done
Security checks
Confirm safety, privacy, and package integrity signals.
Review safety notesRequired
Safety notes are present.
Done
Review privacy notesRequired
Privacy notes are present.
Done
Verify package integrity metadata
No package verification/checksum metadata.
Pending
Rollout
Adopt in controlled steps based on the selected plan.
Run in isolated sandbox firstRequired
Use a constrained sandbox and observe behavior across multiple tasks.
Pending
Roll out graduallyRequired
Roll out to a small cohort before wider usage.
Pending
Set monitoring and fallback
Define rollback path and monitor errors after adoption.
Pending
Evidence readiness
Evidence readiness matrix · balanced
Required evidence gates are covered (5/6 signals complete).
Risk 15
Source provenance
Present
Source repository/provenance is listed.
Required in this preset
Metadata review
Present
Review metadata is present.
Required in this preset
Safety notes
Present
Safety notes are present.
Required in this preset
Privacy notes
Present
Privacy notes are present.
Optional in this preset
Package integrity
Missing
Package integrity metadata is missing.
Optional in this preset
Install payload
Present
Install payload is available.
Required in this preset
Required evidence gates are covered for this preset.
Decision timeline
Decision timeline · balanced
5/6 steps complete with no blocking gaps for this preset.
Risk 14
triage
Confirm source provenanceRequired
Source/provenance metadata is available.
Done
triage
Check metadata review statusRequired
Review metadata is available.
Done
verify
Review safety notesRequired
Safety notes are available.
Done
verify
Review privacy notes
Privacy notes are available.
Done
verify
Validate package integrity metadata
Package integrity metadata is missing.
Pending
rollout
Verify install payload and commandsRequired
Install payload is available.
Done
No required blockers for this timeline preset.
Prerequisite readiness
Prerequisite readiness
4 prerequisites to line up before setup. Includes a review or approval gate.
0/4 ready
Install & runtime1Review & approval1General2
Safety & privacy surface
Safety & privacy surface
5 safety and 3 privacy notes across 6 risk areas. Review closely: credentials & tokens, permissions & scopes, network access.
6 areas
SafetyLocal filesThis hook runs `biome check` without `--write`, so it reports formatter, linter, and import-sorting diagnostics but does not modify files.
SafetyGeneralDo not add `--write` or `--unsafe` until the team has reviewed the hook behavior, backup expectations, and failure mode for generated edits.
SafetyGeneralThe hook exits non-zero when Biome reports diagnostics. Depending on Claude Code settings, this can interrupt the current workflow until issues are reviewed.
SafetyNetwork accessUse a project-pinned Biome package when possible. The script prefers `./node_modules/.bin/biome` and avoids network-install fallbacks.
SafetyPermissions & scopesKeep matchers scoped to write/edit tools. Running Biome after every tool call can add noise and slow down large projects.
PrivacyLocal filesBiome diagnostics can include file paths, rule names, code excerpts, import names, comments, and source snippets from edited files.
PrivacyExecution & processesClaude Code hook logs, terminal scrollback, screenshots, support tickets, and AI transcripts can retain Biome diagnostics outside the repository.
PrivacyCredentials & tokensAvoid pasting real customer code, private filenames, generated secrets, or proprietary source excerpts from hook output into public issue comments.
Safety notes
This hook runs `biome check` without `--write`, so it reports formatter, linter, and import-sorting diagnostics but does not modify files.
Do not add `--write` or `--unsafe` until the team has reviewed the hook behavior, backup expectations, and failure mode for generated edits.
The hook exits non-zero when Biome reports diagnostics. Depending on Claude Code settings, this can interrupt the current workflow until issues are reviewed.
Use a project-pinned Biome package when possible. The script prefers `./node_modules/.bin/biome` and avoids network-install fallbacks.
Keep matchers scoped to write/edit tools. Running Biome after every tool call can add noise and slow down large projects.
Privacy notes
Biome diagnostics can include file paths, rule names, code excerpts, import names, comments, and source snippets from edited files.
Claude Code hook logs, terminal scrollback, screenshots, support tickets, and AI transcripts can retain Biome diagnostics outside the repository.
Avoid pasting real customer code, private filenames, generated secrets, or proprietary source excerpts from hook output into public issue comments.
Prerequisites
Claude Code project where hooks are allowed by user or project policy.
Project-local Biome install, usually `pnpm add -D @biomejs/biome` or the equivalent package-manager command.
`jq` available on the machine to parse Claude Code hook input.
A reviewed `.claude/settings.json` or user settings hook configuration for `Write`, `Edit`, and `MultiEdit`.
Schema details
Install type
cli
Reading time
7 min
Difficulty score
63
Troubleshooting
Yes
Breaking changes
No
Source repository stats
Scope
Source repo
Runtime and command metadata
Trigger
PostToolUse
Script language
bash
Script body
#!/usr/bin/env bash
set -uo pipefail
input="$(cat)"
if ! command -v jq >/dev/null 2>&1; then
echo "Biome hook skipped: jq is required to parse Claude Code hook input." >&2
exit 0
fi
tool_name="$(printf '%s' "$input" | jq -r '.tool_name // .toolName // empty')"
file_path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // .tool_input.path // .toolInput.file_path // .toolInput.path // empty')"
case "$tool_name" in
Write|Edit|MultiEdit|write|edit|multiedit) ;;
*) exit 0 ;;
esac
if [ -z "$file_path" ] || [ ! -f "$file_path" ]; then
exit 0
fi
case "$file_path" in
*.js|*.jsx|*.ts|*.tsx|*.mjs|*.mts|*.cjs|*.cts|*.json|*.jsonc|*.css|*.graphql|*.gql) ;;
*) exit 0 ;;
esac
if [ -x ./node_modules/.bin/biome ]; then
biome_cmd=(./node_modules/.bin/biome)
elif command -v biome >/dev/null 2>&1; then
biome_cmd=(biome)
elif command -v pnpm >/dev/null 2>&1 && pnpm exec biome --version >/dev/null 2>&1; then
biome_cmd=(pnpm exec biome)
elif command -v npm >/dev/null 2>&1 && npx --no-install biome --version >/dev/null 2>&1; then
biome_cmd=(npx --no-install biome)
else
echo "Biome hook skipped: install @biomejs/biome in this project to enable read-only checks." >&2
exit 0
fi
echo "Biome hook: checking $file_path" >&2
"${biome_cmd[@]}" check --no-errors-on-unmatched "$file_path"
status=$?
if [ "$status" -ne 0 ]; then
echo "Biome hook: diagnostics found. Review output before asking Claude to continue." >&2
fi
exit "$status"
This hook runs Biome's check command after Claude Code writes or edits a file
that Biome can handle. It is intentionally read-only: it reports diagnostics and
exits non-zero when Biome finds issues, but it does not pass --write,
--unsafe, start the Biome daemon, or create formatter changes automatically.
Use it when a project already uses Biome and you want immediate feedback after
Claude changes JavaScript, TypeScript, JSON, CSS, or GraphQL files.
Requirements
Claude Code hooks enabled in user or project settings.
Biome installed in the project, preferably as a pinned dev dependency.
jq installed locally so the script can read Claude Code hook input.
A reviewed hook configuration scoped to Write, Edit, and MultiEdit.
Hook Configuration
Add the hook command to .claude/settings.json or the appropriate user-level
Claude Code settings file:
Save this as .claude/hooks/biome-check.sh and make it executable:
#!/usr/bin/env bash
set -uo pipefail
input="$(cat)"
if ! command -v jq >/dev/null 2>&1; then
echo "Biome hook skipped: jq is required to parse Claude Code hook input." >&2
exit 0
fi
tool_name="$(printf '%s' "$input" | jq -r '.tool_name // .toolName // empty')"
file_path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // .tool_input.path // .toolInput.file_path // .toolInput.path // empty')"
case "$tool_name" in
Write|Edit|MultiEdit|write|edit|multiedit) ;;
*) exit 0 ;;
esac
if [ -z "$file_path" ] || [ ! -f "$file_path" ]; then
exit 0
fi
case "$file_path" in
*.js|*.jsx|*.ts|*.tsx|*.mjs|*.mts|*.cjs|*.cts|*.json|*.jsonc|*.css|*.graphql|*.gql) ;;
*) exit 0 ;;
esac
if [ -x ./node_modules/.bin/biome ]; then
biome_cmd=(./node_modules/.bin/biome)
elif command -v biome >/dev/null 2>&1; then
biome_cmd=(biome)
elif command -v pnpm >/dev/null 2>&1 && pnpm exec biome --version >/dev/null 2>&1; then
biome_cmd=(pnpm exec biome)
elif command -v npm >/dev/null 2>&1 && npx --no-install biome --version >/dev/null 2>&1; then
biome_cmd=(npx --no-install biome)
else
echo "Biome hook skipped: install @biomejs/biome in this project to enable read-only checks." >&2
exit 0
fi
echo "Biome hook: checking $file_path" >&2
"${biome_cmd[@]}" check --no-errors-on-unmatched "$file_path"
status=$?
if [ "$status" -ne 0 ]; then
echo "Biome hook: diagnostics found. Review output before asking Claude to continue." >&2
fi
exit "$status"
How It Works
Reads Claude Code hook input from stdin.
Ignores non-edit tools.
Ignores unsupported file extensions.
Prefers a project-local ./node_modules/.bin/biome executable.
Falls back to an existing global biome, pnpm exec biome, or
npx --no-install biome without installing packages from the network.
Runs biome check --no-errors-on-unmatched <file>.
Exits with Biome's status so the user sees diagnostics before continuing.
Safety Notes
This is a diagnostic hook, not an auto-fixer.
Keep it read-only until a team explicitly accepts automated formatting after
every AI edit.
Avoid broad matchers such as all tool calls or all file paths.
Treat non-zero exits as a review stop, not proof that Claude should blindly
rewrite the file.
Keep the project-local Biome version pinned so local and CI results match.
Privacy Notes
Biome diagnostics may include source excerpts, file paths, import specifiers,
rule names, and snippets of edited code. Treat hook output as potentially
sensitive and avoid copying it into public comments when it contains proprietary
source or customer data.
Duplicate And Source Review
Current HeyClaude content already has a Biome rules entry and generic hook
generator examples that mention biome check --write. This entry is different:
it is a dedicated Claude Code hook, defaults to read-only diagnostics, and is
source-backed by Biome's CLI docs and official repository.
Troubleshooting
Issue: The hook never runs
Fix: Check the Claude Code hook matcher, script path, executable bit, and
whether the edited file extension is included in the script allowlist.
Issue: The hook says Biome is not installed
Fix: Install Biome as a project dev dependency, for example
pnpm add -D @biomejs/biome, then confirm ./node_modules/.bin/biome version
works from the project root.
Issue: The hook blocks too often
Fix: Keep the hook read-only but narrow the matcher or extension list.
Consider running it only for files that already live under Biome-managed paths.
Issue: The hook output exposes private code
Fix: Keep diagnostics local, redact snippets before sharing, and avoid
posting hook output to public PRs, issues, chats, or screenshots.
Issue: Claude keeps trying to auto-fix every diagnostic
Fix: Tell Claude to summarize Biome diagnostics first, group them by rule,
and ask before applying changes. Do not add --write unless that behavior is
explicitly approved.
Show that Biome Check Hook for Claude Code is listed on HeyClaude. Paste this Markdown into your README — it renders the badge and links back to this page.
[](https://heyclau.de/entry/hooks/biome-check-hook)
How it compares
Biome Check Hook for Claude Code side by side with 3 alternatives on trust, install, platform support, and disclosed safety notes — all from reviewed registry metadata.
Read-only Claude Code PostToolUse hook that runs Biome's formatter, linter, and import-sorting checks on edited JavaScript, TypeScript, JSON, CSS, and GraphQL files without auto-writing changes.
Read-only Claude Code PostToolUse hook that runs shfmt diff checks after Claude writes or edits shell scripts, surfacing POSIX shell, Bash, Zsh, and mksh formatting drift without rewriting files or executing scripts.
Read-only Claude Code PostToolUse hook that runs Hadolint diagnostics after Claude writes or edits Dockerfile-like files, surfacing Dockerfile best practice, inline shell, trusted registry, label, and configuration findings without rewriting files.
Read-only Claude Code PostToolUse hook that runs ShellCheck diagnostics after Claude writes or edits shell scripts, reporting shell portability, quoting, expansion, error-handling, and command-safety issues without modifying files.
✓This hook runs `biome check` without `--write`, so it reports formatter, linter, and import-sorting diagnostics but does not modify files.
Do not add `--write` or `--unsafe` until the team has reviewed the hook behavior, backup expectations, and failure mode for generated edits.
The hook exits non-zero when Biome reports diagnostics. Depending on Claude Code settings, this can interrupt the current workflow until issues are reviewed.
Use a project-pinned Biome package when possible. The script prefers `./node_modules/.bin/biome` and avoids network-install fallbacks.
Keep matchers scoped to write/edit tools. Running Biome after every tool call can add noise and slow down large projects.
✓This hook runs `shfmt -d` only. It does not pass `-w`, rewrite files, run scripts, install tools, invoke Docker, or execute code from the edited file.
The hook exits non-zero when shfmt prints a diff or reports a parse error. Depending on Claude Code settings, this can interrupt the workflow until a human reviews the output.
Keep the hook scoped to write/edit tools. Running shfmt after every tool call can add noise and slow down shell-heavy projects.
Formatting diffs are style feedback, not a security review. Pair this with ShellCheck, tests, and human review for command safety.
shfmt supports POSIX shell, Bash, Zsh, and mksh syntax, but project-specific style choices may still require a team policy.
Do not enable automatic rewriting until the team has agreed on shfmt style and reviewed the effect on existing scripts.
✓This hook runs a local `hadolint --format gnu` command only. It does not build images, run containers, pull base images, install Hadolint, rewrite files, or execute Dockerfile instructions.
The hook exits non-zero when Hadolint reports diagnostics. Depending on Claude Code settings, this can interrupt the workflow until a human reviews the output.
Keep the hook scoped to write/edit tools. Running Hadolint after every tool call can add noise and slow down projects with generated Dockerfiles.
Hadolint findings are static-analysis findings, not proof that an image build is safe, reproducible, minimal, or vulnerability-free.
Hadolint can respect project configuration files and inline ignore pragmas. Review `.hadolint.yaml` and ignored rules before treating a clean result as sufficient.
This script intentionally avoids the official Docker and Podman invocation paths so a hook run does not require Docker socket access or container image pulls.
Review base image trust, package manager commands, copied files, build secrets, and runtime privileges separately from this hook.
✓This hook runs `shellcheck --format=gcc` only. It does not add `--external-sources`, install dependencies, rewrite files, run scripts, source scripts, or execute commands from the edited file.
The hook exits non-zero when ShellCheck reports diagnostics. Depending on Claude Code settings, this can interrupt the workflow until a human reviews the output.
Keep the hook scoped to write/edit tools. Running ShellCheck after every tool call can add noise and slow down shell-heavy projects.
ShellCheck warnings are static-analysis findings, not proof that a script is safe. Review command execution, permissions, inputs, secrets, paths, and deployment context separately.
ShellCheck can follow sourced files when configured to do so. This script avoids `--external-sources` by default so it does not traverse additional project files unexpectedly.
Do not use this hook as a blanket command blocker. It is intended to surface diagnostics after Claude edits shell files, not to approve or deny arbitrary terminal commands.
Privacy notes
✓Biome diagnostics can include file paths, rule names, code excerpts, import names, comments, and source snippets from edited files.
Claude Code hook logs, terminal scrollback, screenshots, support tickets, and AI transcripts can retain Biome diagnostics outside the repository.
Avoid pasting real customer code, private filenames, generated secrets, or proprietary source excerpts from hook output into public issue comments.
✓shfmt diffs can include file paths, comments, commands, variable names, hostnames, internal paths, and source snippets from edited shell scripts.
Hook output can be retained in Claude Code logs, terminal scrollback, screenshots, support tickets, issue comments, or AI transcripts.
Avoid pasting proprietary deployment scripts, customer paths, secret variable names, generated tokens, hostnames, or production command output into public comments or prompts.
Use synthetic examples when sharing shfmt findings publicly, and review diff output before exposing private repository structure.
✓Hadolint diagnostics can include file paths, image names, registry hostnames, labels, build arguments, environment variable names, comments, and Dockerfile snippets.
Dockerfiles can reveal private registry names, internal service names, proprietary package mirrors, deployment paths, and application structure.
Hook output can be retained in Claude Code logs, terminal scrollback, screenshots, support tickets, issue comments, or AI transcripts.
Avoid pasting proprietary Dockerfiles, private image names, customer deployment paths, secret variable names, or internal registry details into public comments or prompts.
✓ShellCheck diagnostics can include file paths, line numbers, command names, variable names, comments, and source snippets from edited shell scripts.
Hook output can be retained in Claude Code logs, terminal scrollback, screenshots, support tickets, issue comments, or AI transcripts.
Avoid pasting proprietary deployment scripts, customer paths, secret variable names, generated tokens, hostnames, or production command output into public comments or prompts.
Use synthetic examples when sharing ShellCheck findings publicly, and review diagnostics before exposing private repository structure.
Prerequisites
Claude Code project where hooks are allowed by user or project policy.
Project-local Biome install, usually `pnpm add -D @biomejs/biome` or the equivalent package-manager command.
`jq` available on the machine to parse Claude Code hook input.
A reviewed `.claude/settings.json` or user settings hook configuration for `Write`, `Edit`, and `MultiEdit`.
Claude Code project where hooks are allowed by user or project policy.
shfmt installed locally and available on `PATH`, for example through Go install, Homebrew, a system package, or another official release path.
`jq` available on the machine to parse Claude Code hook input.
A reviewed `.claude/settings.json` or user settings hook configuration for `Write`, `Edit`, and `MultiEdit`.
Claude Code project where hooks are allowed by user or project policy.
Hadolint installed locally and available on `PATH`, for example through an operating system package manager or official release path.
`jq` available on the machine to parse Claude Code hook input.
A reviewed `.claude/settings.json` or user settings hook configuration for `Write`, `Edit`, and `MultiEdit`.
Claude Code project where hooks are allowed by user or project policy.
ShellCheck installed on the machine, for example through the operating system package manager or the official ShellCheck release path.
`jq` available on the machine to parse Claude Code hook input.
A reviewed `.claude/settings.json` or user settings hook configuration for `Write`, `Edit`, and `MultiEdit`.