Skip to content

refactor(lint): make frontend/package.json the only Biome version - #88

Merged
sirjmann92 merged 1 commit into
mainfrom
chore/biome-single-source
Sep 18, 2026
Merged

sirjmann92 merged 1 commit into
mainfrom
chore/biome-single-source

Conversation

@sirjmann92

Copy link
Copy Markdown
Owner

Collapses five Biome version declarations into one, and deletes the guard that existed to police them.

The problem

Biome ran through the remote biomejs/pre-commit hook. Pre-commit fetches its own hermetic copy of a hook's tool and deliberately never looks at frontend/node_modules — so that copy needed its own version number. Combined with the npm pin, the lockfile, and biome.json's $schema, one fact was stated five times.

Drift between them failed silently, the gate quietly enforcing whichever ruleset the hook's copy happened to be. That is how this repo once ran 2.2.4 against a declared 2.5.11, nine releases apart (#81).

scripts/check_biome_pins.py turned that silence into a loud failure, which was the right immediate call. But it made every Biome bump a two-PR affair: Dependabot can only reach two of the five pins, so its PR failed CI by construction — most recently #85, which needed #86 to land first.

The fix

Biome now runs as a repo: local hook invoking npm run lint — the same command a developer runs by hand, and the pattern svelte-check already used in this very file. The version comes from node_modules, so frontend/package.json is the single source of truth and the guard has nothing left to check.

Declared in Before After
frontend/package.json 2.5.13 the only one
frontend/package-lock.json 2.5.13 maintained by npm
.pre-commit-config.yaml rev v2.5.13 gone
.pre-commit-config.yaml additional_dependencies 2.5.13 gone
biome.json $schema pinned URL points at the installed copy

A future @biomejs/biome bump from Dependabot now passes CI unaided.

A bug found along the way

File scoping lived in the hook's files: regex, and had never been in biome.json at all. So npm run lint — the documented lint command — had no scoping whatsoever: it swept frontend/.svelte-kit/ generated output and reported 1600 errors and 3996 warnings. CI never invokes that script, so nobody noticed.

Scoping now lives in biome.json's files.includes, where it belongs. Both the hook and the npm script check the same 26 files, and npm run lint is usable again.

Verification

  • pre-commit run --all-files — 15/15 hooks pass (was 16; the guard is gone)
  • Coverage is unchanged: the file set Biome checks is identical before and after — 26 files, the same 26. The 27th match of the old regex was package-lock.json, which Biome ignores internally either way.
  • The gate still has teeth: injected a formatting violation into frontend/src/lib/types.ts, confirmed biome check fails on it, restored the file, confirmed it passes.
  • npm run lint — 26 files, clean.

Tradeoffs

  • The hook needs frontend/node_modules to exist. Already true for svelte-check, already mandated by AGENTS.md, and CI runs npm ci before pre-commit.
  • Pre-commit's hermeticity is traded for the lockfile's determinism. npm ci is reproducible, so this is a small, deliberate loss.

AGENTS.md is updated in the same PR per the rule added in #84 — the five-pin section is rewritten to describe the single source and the two things that follow from it.

Biome ran through the remote biomejs/pre-commit hook, which fetches its
own hermetic copy and never looks at frontend/node_modules. That copy
needed its own version, so one fact — which Biome this repo uses — was
declared five times: the npm pin, the lockfile, the hook rev, the hook's
additional_dependencies, and biome.json's $schema URL.

Drift between them failed silently, the gate quietly enforcing the older
ruleset; that is how the repo once ran 2.2.4 against a declared 2.5.11
(issue #81). scripts/check_biome_pins.py turned that silence into a loud
failure, but it made every Biome bump a two-PR affair: Dependabot can
only reach two of the five pins, so its PR failed CI by construction.

Biome now runs as a repo: local hook invoking `npm run lint` — the same
command a developer runs, and the pattern svelte-check already used. The
version comes from node_modules, so package.json is the single source of
truth and the guard has nothing left to check.

Also moves file scoping out of the hook's regex into biome.json's
files.includes, where it belongs. It had never been in biome.json at all,
so `npm run lint` was unscoped: it swept frontend/.svelte-kit/ and emitted
~5600 diagnostics, making the documented lint command unusable. Both the
hook and the npm script now check the same 26 files.

Coverage is unchanged — verified the same file set before and after, and
verified the hook still fails on an injected formatting violation.
@sirjmann92
sirjmann92 merged commit 06bc58b into main Sep 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant