
# Introduction

[OXC](https://oxc.rs) is a JavaScript and TypeScript toolchain written in
Rust: a parser, the `oxlint` linter, and the `oxfmt` formatter. It does the
same jobs as ESLint and Prettier, just much faster.

OXC for TSRX teaches those tools to read `.tsrx` files, so you can lint and
format them like any other file in your project. The parser behind them is
also available as a library, [`oxc-tsrx/parser`](/guide/parsing), for
building your own tooling.

## The problem it solves

TSRX is TypeScript/JSX plus template control flow: `@if`, `@for`, `@switch`,
`@try`, `@{ }` statement containers (a successor and extension of JSX
expression containers), dynamic tags like `<{expr}>`, and inline raw
`<style>` blocks.

OXC on its own doesn't understand TSRX. Point `oxlint` or `oxfmt` at a
`.tsrx` file and they see a parse error at the first `@if`. So TSRX projects
would normally lose linting and formatting entirely. That's the gap this
project closes.

## How it works, in plain terms

OXC only understands regular TS/TSX, so every `.tsrx` file goes through the
same four steps.

1. **Scans** the file once and records where the TSRX-only syntax is.
2. **Projects** it: builds an in-memory copy where each TSRX construct is
   swapped for equivalent, valid TSX placeholders. Your real code between
   those constructs is copied byte-for-byte, and the tool remembers exactly
   which byte ranges are "your code" and which are placeholder.
3. **Runs the real OXC** (parser, then linter or formatter) on that copy.
   Exactly once. Even dynamic tags are validated against this same parse.
4. **Maps the results back** to your original file. Lint errors point at your
   actual `.tsrx` lines and columns. For formatting, a final step (the
   *lift*) converts the formatted TSX copy back into TSRX and double-checks
   that nothing structural changed.

Your file on disk is always real TSRX. The TSX copy never touches disk; it
exists only so OXC can do its job.

Ordinary `.js`, `.jsx`, `.ts`, and `.tsx` files skip all of this and go
straight to OXC, byte-for-byte identical to running `oxlint` and `oxfmt`
yourself.

## What it promises

- ✅ **Real rules, your config.** OXC's own lint rules and Oxfmt's own
  formatting, driven by the `.oxlintrc.json` and `.oxfmtrc.json` you already
  have. In a Vite+ project, `vp lint` reads the `lint` block of your
  `vite.config.ts` instead.
- 🎯 **Errors point at your code.** Every warning lands on a line you actually
  wrote. Ones that fire on the hidden placeholder code are counted, not shown.
- 🛡️ **Safe fixes.** `--fix` edits your original TSRX and confirms the result
  still parses before writing anything.
- 🧠 **Opt-in type-aware rules.** `--type-aware` adds the official tsgolint
  rules, `--type-check` adds full TypeScript diagnostics. The default lane
  starts zero type processes. See [Linting](/guide/linting).
- ✏️ **Editor support.** The official OXC extension picks up the project-local
  `oxlint` that `oxc-tsrx` installs, and your `.tsrx` files get live
  diagnostics, formatting, and quick fixes. Your `.ts` and `.tsx` files keep
  working exactly as before. See [Editor integration](/integrations/editor).
- 🔗 **No fork.** Nothing is snapshotted and nothing is patched. Every OXC call
  lives in one small adapter crate, so upgrading OXC means updating that one
  crate.
- 🚦 **Fail closed.** Unsupported TSRX syntax gets a clear error, never a
  silently skipped file or a half-right result.

## The commands

Install `oxc-tsrx` and you get the familiar commands, now with TSRX support:

Real output, captured at build time. The sample project has a src/Counter.tsrx with a debugger statement and an unformatted src/View.tsx with an unused variable.

```text
# Lint .tsrx and ordinary JS/TS with real OXC rules
$ npx oxlint src/Counter.tsrx src/View.tsx
src/Counter.tsrx:4:3: warning eslint(no-debugger): `debugger` statement is not allowed
src/View.tsx:2:7: warning eslint(no-unused-vars): Variable 'seen' is declared but never used. Unused variables should start with a '_'. help: Consider removing this declaration.
Found 0 error(s) and 2 warning(s).

# Format .tsrx and ordinary JS/TS with real Oxfmt layout
$ npx oxfmt --check src/Counter.tsrx src/View.tsx
Checking formatting...

src/View.tsx (0ms)
src/Counter.tsrx (1ms)

Format issues found in above 2 files. Run without `--check` to fix.
Finished in 86ms on 2 files using 18 threads.
No config found, using defaults. Please add a config file or try `oxfmt --init` if needed.
```

Every command is the same native Rust binary, `oxc-tsrx`: the linter, the
formatter, and the editor language server in one download, picked by
subcommand. See [Getting Started](/guide/getting-started) to install it and the
[CLI reference](/reference/cli) for every flag.

## What it deliberately is not

- **Not a compiler.** Your framework's TSRX plugin, installed from
  [tsrx.dev/getting-started](https://tsrx.dev/getting-started), owns
  compilation, CSS, source maps, and HMR. Nothing here touches your build or dev
  server. See [Vite and Vite+](/integrations/vite-plus).
- **Not a CSS formatter.** Anything inside a raw `<style>` block is left alone,
  byte for byte.
- **Not finished.** Some syntax and config options aren't supported yet. They
  fail with a clear error instead of quietly doing the wrong thing. See
  [Limitations](/reference/limitations).
