Skip to content

Oxlint Type-Aware Preview


We're thrilled to announce type-aware rules support in Oxlint!

This preview release aims to engage with the community for collaboration and discussion by documenting our decision process and technical details.

Quick Start ​

If oxlint isn't already installed, please visit our usage guide.

To get started, run:

bash
pnpm add -D oxlint-tsgolint
oxlint --tsconfig tsconfig.json

You'll then see two of our most requested type-aware rules in action:

  • no-floating-promises
  • no-misused-promises

The next version will enable all type-aware rules.

Performance ​

Our testing shows that large repositories, which previously took several minutes to run with typescript-eslint, now complete in less than 10 seconds.

We achieved this by leveraging typescript-go, the 10x faster TypeScript written in Go.

Type-Aware linting ​

Please refer to Rust-Based JavaScript Linters: Fast, But No Typed Linting Right Now to understand the current status of type-aware linting in the ecosystem.

Technical Details ​

The core of this new functionality is oxc-project/tsgolint.

The tsgolint project was initially prototyped as typescript-eslint/tsgolint. However, the typescript-eslint team decided not to allocate development resources to this prototype, as they plan to continue their work on typescript-eslint for typed linting with ESLint.

@boshen then reached out to @auvred for a forked, scoped-down version adapted for oxlint. This version would only contain type-aware rules without the sophisticated configuration resolution a full linter would require.

@auvred generously offered to continue its development under the Oxc organization.

Architecture ​

oxlint (written in Rust) and tsgolint (written in Go) are compiled into their own binaries.

oxlint serves as the "frontend" for tsgolint, handling the CLI, path traversal, ignore logic, and diagnostic printing.

tsgolint acts as the backend for oxlint, accepting paths and configuration as input and outputting structured diagnostics.

This creates a simple pipeline:

Oxlint CLI (returns paths + rules + configuration)
  -> tsgolint (returns diagnostics)
  -> Oxlint CLI

tsgolint ​

tsgolint does not communicate with typescript-go via public APIs.

Instead, it compiles typescript-go by shimming its internal APIs to make them public.

All type-aware rules are written directly against these shimmed APIs.

While this isn't the recommended approach for accessing internals, it works!

Decision Process ​

Write our own type checker ​

Previous abandoned attempts to implement a type checker included:

Additionally, there's the work-in-progress:

  • Biome 2.0 with its own type inference implementation.

We determined that writing our own type inferencer or type checker was not feasible due to the challenge of keeping up with a fast-moving target like TypeScript.

Communication with TypeScript ​

Prior to typescript-go, projects added plugin interfaces to TypeScript's public API by either mapping its AST to estree or directly traversing the TypeScript AST. Examples include:

We also explored inter-process communication with Oxlint but abandoned the idea.

With typescript-go, the TypeScript team is leaning towards encoding the TypeScript AST and decoding it on the JavaScript side through inter-process communication.

While these approaches work, they still incur:

  • Performance issues of varying degrees that don't suit Oxlint's performance characteristics.
  • The cost of maintaining an AST mapping from TypeScript's AST.

Considerations ​

While tsgolint solves the performance issue, there are other technical challenges that need to be addressed.

Requirement for a Different TypeScript Version ​

We plan to release snapshots of typescript-go versions and align their version numbers with TypeScript. You will then be able to install oxlint-typescript with the correct TypeScript version.

The downside of this approach is that you may need to upgrade TypeScript if oxlint-tsgolint requires changes.

Maintenance cost of tsgolint ​

Shimming TypeScript's internal APIs carries some risk. However, the TypeScript AST and its visitor are actually quite stable. We accept this risk and will fix breaking changes when upgrading typescript-go.

Our typescript-go version is synced three times a week.

Acknowledgements ​

We'd like to extend our gratitude to:

  • The TypeScript team for creating typescript-go.
  • @auvred for creaging tsgolint.
  • @camchenry for the oxlint + tsgolint integration.
  • The typescript-eslint team for their heartwarming support.

Join the Community ​

We'd love to hear your feedback on Oxlint and type-aware linting and are excited to see how it helps improve your development workflow. Connect with us:

Give It a Try ​

To get started, follow the installation guide, or learn more about the Oxc project.

Released under the MIT License.