OXC for TSRX
A parser, linter, formatter, and language server for .tsrx
One install, and your .tsrx files lint and format like .tsx does.
export function TaskList({ tasks }: Props) @{
const pending = tasks.filter((task) => !task.done);
<section class="tasks">
@if (pending.length > 0) {
@for (const task of pending; key task.id) {
<TaskRow task={task} />;
} @empty {
<AllDone />;
}
} @else {
<SignIn />;
}
<style>
.tasks { display: grid; gap: 0.5rem; }
</style>
</section>;
}
Fast, and gated on it
A release gate is an automated pass or fail check that runs before every release. Each benchmark below has a frozen budget, meaning the worst result we allow ourselves to ship. If a new build ever lands on the wrong side of a budget, the release fails and does not go out. Every number below is read from the committed benchmark reports when this site is built. Measured 2026-07-17 on one machine; your hardware will differ.
Lint the same 1,000 files, three tools
Bar lengths show absolute median wall-clock time. Matched cross-tool bars use the same 1000 TSX files with one rule; the separately patterned mixed bar is the paired internal workload of mixed file types (TSX plus TSRX). Every tool crosses the npm boundary: each time is the npm command a project actually runs, Node launcher included. Shorter is faster.
Methodology, versions, and gates
All three tools lint the same explicit list of 1000 byte-identical TSX files (515 KiB) with the no-debugger rule and zero-diagnostic default output, on the same machine (Apple M5 Pro). Every lane is measured through its npm CLI entry point, so each time includes that tool's own Node launcher. For the all-TSX product lane, oxlint-tsrx imports the exact manifest-declared official Oxlint launcher in the same Node process with zero TSRX dispatch. The separate mixed-file-types lane (20% TSRX by file count) proves 1 public canonical Node child, 1 native TSRX child, and 0 private adapter children; it is a paired internal workload, not a cross-tool comparison. Each time is the median of 20 measured processes after 5 warmups. Hover any bar for its frozen ratio gate: the release fails if a future build breaks it. Versions: ESLint v10.7.0 with typescript-eslint 8.64.0; official Oxlint 1.74.0. Report benchmarks/comparative/results-1784321699288.json (2026-07-17).
Release gates we ship against
Each card is one release gate: the big number is the measured value, and the thin bar shows how close it sits to its frozen budget (the dashed line). If a result ever crosses its budget, the release fails. Hover or focus a card for what exactly is measured.
-
Built on OXC, not a copy
Nothing is snapshotted and nothing is patched. Every OXC call lives in one small adapter crate.
-
A real parser you can call
Same API shape as official
oxc-parser, plus.tsrx, for codemods, bundler plugins, and analysis tools. -
Squiggles where you typed
Real OXC rules run on a temporary in-memory TSX copy, but what you see is anchored to your authored source.
-
Formatting that checks itself
Oxfmt layout is carried back into your TSRX, then reparsed and compared before anything reaches disk.
-
Speed you can check
Every number on this page is read from a committed benchmark report when the site is built.
-
Your editor already knows
The released official OXC VS Code extension picks up the project-local
oxlintthatoxc-tsrxinstalls, then gets live.tsrxdiagnostics, formatting, and validated quick fixes.
We want to upstream this to OXC
OXC for TSRX is an independent community project, and its end goal is for TSRX support to live in OXC itself. The reusable language core is kept small, isolated, and benchmark-gated so that OXC maintainers can review it with as little effort as possible. No OXC maintainer interest or endorsement is claimed.