Skip to content

chore: replace Biome with oxlint, oxfmt and Knip - #14

Open
Thomasims wants to merge 6 commits into
mainfrom
chore/oxc-tooling
Open

chore: replace Biome with oxlint, oxfmt and Knip#14
Thomasims wants to merge 6 commits into
mainfrom
chore/oxc-tooling

Conversation

@Thomasims

@Thomasims Thomasims commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Moves this repository off Biome and onto the shared
@antelopejs/tooling-configs
presets, in step with the rest of the ecosystem.

Tooling swap

  • @biomejs/biome and biome.json are gone.
  • oxlint (pinned to 1.81.0, the version the presets' JS plugin API matches),
    oxfmt, knip, oxlint-tsgolint and eslint-plugin-perfectionist come in as
    dev dependencies.
  • New oxlint.config.ts, oxfmt.config.ts and knip.config.ts, each extending
    the shared preset.
  • Scripts: lintoxlint, lint:fixoxlint --fix, formatoxfmt .,
    plus new format:check and knip. Every other script is untouched.

The .github/ISSUE_TEMPLATE/** ignore in oxfmt.config.ts is temporary: those
files are Markdown templates with a .yml extension, 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 removed node10) is dropped, and baseUrl
goes with it — the two self-referential paths entries the suites use to import
the package by its own name become relative (./src/index.ts, ./src/*), which
is what baseUrl: "." resolved them to anyway.

"module": "commonjs" deliberately stays. Raising it to node16 looks like the
obvious fix and is a runtime break: tsc would stop downlevelling dynamic imports
and emit native ESM ones, bypassing the CommonJS resolver detour the ajs
runtime installs.

What the linter forced

Import order, and nothing else — 57 perfectionist(sort-imports) errors on
origin/main, all autofixed (two oxlint --fix passes: the first clears 23 and
reports the 34 that a second pass then fixes). import(no-cycle) found no
cycles 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/noThisInStatic directive in
src/table.ts suppressed nothing once Biome was removed, so the directive was
dropped and its explanation kept as a plain comment.

Knip

The suites needed declaring as entry points. They live in src/tests/, which
the preset's src/test/ glob does not match, and ajs module test runs them
from the compiled output while reading src/antelope.test.ts (named by
antelopeJs.test) to build the test project. Without that, the whole suite plus
chai, @types/chai and mongodb-memory-server-core read as dead.

The entry glob is src/tests/**/*.ts, not just **/*.test.ts, so it takes in
src/tests/codec_helpers.ts as well. The whole compiled tree ships in the
package 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 every
module'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

  • Public surface unchanged. dist was built from untouched origin/main
    and from this branch, and the runtime export keys of every module behind the
    exports map (., ./common, ./database, ./model, ./relation,
    ./schema, ./table and the five ./modifiers/* subpaths) were diffed:
    identical. Before the import sort, the entire dist tree was byte-identical
    to the baseline, which confirms the tsconfig change alone changes no emit.
    After it, the only .d.ts differences are reordered import lines in
    model.d.ts and table.d.ts.
  • Tests. pnpm test on untouched origin/main: 102 passing, 0 failing. On
    this branch: 102 passing, 0 failing.
  • pnpm lint, pnpm knip and pnpm build all exit 0.

Commits

The oxfmt pass is its own commit and is recorded in .git-blame-ignore-revs, so
git blame stays readable. oxfmt also normalizes package.json key order and
sorts keywords; that is expected.

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
Thomasims marked this pull request as ready for review September 7, 2026 16:10
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