OXC for TSRX

A parser, linter, formatter, and language server for .tsrx

One install, and your .tsrx files lint and format like .tsx does.

src/TaskList.tsrx
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>;
}
pre-generated example · static preview native lint and format run only on the local development server

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.

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.