chore: replace Biome with oxlint, oxfmt and Knip - #14
Open
Thomasims wants to merge 6 commits into
Open
Conversation
Adopts the shared @antelopejs/tooling-configs presets: oxlint with the vendored anti-slop rules, oxfmt for formatting and Knip for dead code. Type-aware linting needs a tsconfig tsgolint accepts, so the removed moduleResolution node10 and baseUrl options go away and the self-referential path mappings the suites use become relative. The module stays on commonjs so the emit keeps using require, which is what the AntelopeJS resolver hooks; the compiled output is byte-identical apart from the reordered imports the sorter produced. The only fixes the linter forced were import order — import(no-cycle) found no cycles in this tree, and nothing needed disabling. Knip needs the suites declared as entry points: they live under src/tests and are run from the compiled output by `ajs module test`, which the preset's src/test glob does not match. The glob covers the fixtures too, not just the *.test.ts files: the whole compiled tree ships in the package for implementing modules to run as their conformance suite, so codec_helpers.ts is reachable from outside rather than an internal module whose exports Knip can trace. No export changes: this package is a contract, so its surface is reachable only from consumers Knip cannot see.
Biome is gone, so the directives suppress nothing. The explanations they carried are kept as plain comments.
Biome is gone, so they suppressed nothing. AGENTS.md mandates self-documenting code without non-TSDoc comments, so the directives are dropped rather than demoted to plain comments.
Thomasims
marked this pull request as ready for review
September 7, 2026 16:10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Moves this repository off Biome and onto the shared
@antelopejs/tooling-configspresets, in step with the rest of the ecosystem.
Tooling swap
@biomejs/biomeandbiome.jsonare gone.oxlint(pinned to1.81.0, the version the presets' JS plugin API matches),oxfmt,knip,oxlint-tsgolintandeslint-plugin-perfectionistcome in asdev dependencies.
oxlint.config.ts,oxfmt.config.tsandknip.config.ts, each extendingthe shared preset.
lint→oxlint,lint:fix→oxlint --fix,format→oxfmt .,plus new
format:checkandknip. Every other script is untouched.The
.github/ISSUE_TEMPLATE/**ignore inoxfmt.config.tsis temporary: thosefiles are Markdown templates with a
.ymlextension, which oxfmt cannot parse.It goes away once
tooling-configs#5 ships
the shared ignore.
tsconfig
Type-aware linting runs through tsgolint, which rejects compiler options
TypeScript 7 removed and auto-discovers each file's
tsconfig.json. So"moduleResolution": "node"(the removednode10) is dropped, andbaseUrlgoes with it — the two self-referential
pathsentries the suites use to importthe package by its own name become relative (
./src/index.ts,./src/*), whichis what
baseUrl: "."resolved them to anyway."module": "commonjs"deliberately stays. Raising it tonode16looks like theobvious fix and is a runtime break: tsc would stop downlevelling dynamic imports
and emit native ESM ones, bypassing the CommonJS resolver detour the
ajsruntime installs.
What the linter forced
Import order, and nothing else — 57
perfectionist(sort-imports)errors onorigin/main, all autofixed (twooxlint --fixpasses: the first clears 23 andreports the 34 that a second pass then fixes).
import(no-cycle)found nocycles in this tree. Nothing was disabled and no rule was silenced. The 12
remaining oxlint findings are warnings, the deliberate backlog the presets ship
with, left alone here.
One further source edit is unrelated to the linter and lives in its own
chore:commit: the
// biome-ignore lint/complexity/noThisInStaticdirective insrc/table.tssuppressed nothing once Biome was removed, so the directive wasdropped and its explanation kept as a plain comment.
Knip
The suites needed declaring as entry points. They live in
src/tests/, whichthe preset's
src/test/glob does not match, andajs module testruns themfrom the compiled output while reading
src/antelope.test.ts(named byantelopeJs.test) to build the test project. Without that, the whole suite pluschai,@types/chaiandmongodb-memory-server-coreread as dead.The entry glob is
src/tests/**/*.ts, not just**/*.test.ts, so it takes insrc/tests/codec_helpers.tsas well. The whole compiled tree ships in thepackage for the implementing modules to run as their conformance suite, so that
fixture is an outside-reachable surface in its own right rather than an internal
module whose exports Knip can trace.
ignoreBinaries: ["ajs"]matches the rest of the ecosystem: the CLI comes from@antelopejs/core, which CI installs globally rather than pulling into everymodule's dependency tree.
No exports were removed. This package is a versioned contract: its surface is
reachable only from consumers Knip cannot see, so an "unused export" here would
never be evidence of dead code.
Verification
distwas built from untouchedorigin/mainand from this branch, and the runtime export keys of every module behind the
exportsmap (.,./common,./database,./model,./relation,./schema,./tableand the five./modifiers/*subpaths) were diffed:identical. Before the import sort, the entire
disttree was byte-identicalto the baseline, which confirms the tsconfig change alone changes no emit.
After it, the only
.d.tsdifferences are reordered import lines inmodel.d.tsandtable.d.ts.pnpm teston untouchedorigin/main: 102 passing, 0 failing. Onthis branch: 102 passing, 0 failing.
pnpm lint,pnpm knipandpnpm buildall exit 0.Commits
The oxfmt pass is its own commit and is recorded in
.git-blame-ignore-revs, sogit blamestays readable. oxfmt also normalizespackage.jsonkey order andsorts
keywords; that is expected.