|
| 1 | +--- |
| 2 | +title: Type-Aware Linting Alpha |
| 3 | +outline: deep |
| 4 | +authors: |
| 5 | + - cameron |
| 6 | + - camchenry |
| 7 | +--- |
| 8 | + |
| 9 | +<AppBlogPostHeader /> |
| 10 | + |
| 11 | +<br> |
| 12 | + |
| 13 | +We're excited to announce the alpha release of type-aware linting in Oxlint! |
| 14 | + |
| 15 | +## Overview |
| 16 | + |
| 17 | +Following our [technical preview in August](/blog/2025-08-17-oxlint-type-aware), we're excited to announce that type-aware linting has reached alpha status. This milestone brings significant improvements in stability, configurability, and rule coverage. |
| 18 | + |
| 19 | +Type-aware linting enables powerful rules like `no-floating-promises`, `no-misused-promises`, and `await-thenable` that catch bugs by utilizing TypeScript's type system. With 43 type-aware rules now available, you can catch entire categories of runtime errors before they happen. |
| 20 | + |
| 21 | +**In this post:** |
| 22 | + |
| 23 | +- [Quick Start](#quick-start) - Get started with type-aware linting in minutes |
| 24 | +- [Performance](#performance) - See how much faster type-aware linting is compared to ESLint |
| 25 | +- [What's new since the technical preview](#what-s-new-since-the-technical-preview) - New features and improvements |
| 26 | +- [Technical details](#technical-details) - How type-aware linting works under the hood |
| 27 | +- [What's next](#what-s-next) - Upcoming improvements for the beta release |
| 28 | + |
| 29 | +## Quick Start |
| 30 | + |
| 31 | +Install `oxlint` and `oxlint-tsgolint`, then run with the `--type-aware` flag: |
| 32 | + |
| 33 | +::: code-group |
| 34 | + |
| 35 | +```sh [npm] |
| 36 | +npm add -D oxlint oxlint-tsgolint@latest |
| 37 | +npx oxlint --type-aware |
| 38 | +``` |
| 39 | + |
| 40 | +```sh [pnpm] |
| 41 | +pnpm add -D oxlint oxlint-tsgolint@latest |
| 42 | +pnpm oxlint --type-aware |
| 43 | +``` |
| 44 | + |
| 45 | +```sh [yarn] |
| 46 | +yarn add -D oxlint oxlint-tsgolint@latest |
| 47 | +yarn oxlint --type-aware |
| 48 | +``` |
| 49 | + |
| 50 | +```sh [bun] |
| 51 | +bun add -D oxlint oxlint-tsgolint@latest |
| 52 | +bunx oxlint --type-aware |
| 53 | +``` |
| 54 | + |
| 55 | +::: |
| 56 | + |
| 57 | +To try a specific type-aware rule without other configuration (`oxlint-tsgolint` must be installed globally or locally already): |
| 58 | + |
| 59 | +::: code-group |
| 60 | + |
| 61 | +```sh [npm] |
| 62 | +npx oxlint --type-aware -A all -D typescript/no-floating-promises |
| 63 | +``` |
| 64 | + |
| 65 | +```sh [pnpm] |
| 66 | +pnpx oxlint --type-aware -A all -D typescript/no-floating-promises |
| 67 | +``` |
| 68 | + |
| 69 | +```sh [yarn] |
| 70 | +yarn oxlint --type-aware -A all -D typescript/no-floating-promises |
| 71 | +``` |
| 72 | + |
| 73 | +```sh [bun] |
| 74 | +bunx oxlint --type-aware -A all -D typescript/no-floating-promises |
| 75 | +``` |
| 76 | + |
| 77 | +::: |
| 78 | + |
| 79 | +For more configuration options, see our [usage guide](/docs/guide/usage/linter/type-aware). |
| 80 | + |
| 81 | +## Performance |
| 82 | + |
| 83 | +| Project | Oxlint + Type Aware | ESLint + typescript-eslint | Improvement | |
| 84 | +| --------------- | ------------------- | -------------------------- | ----------- | |
| 85 | +| vuejs/core | 2.531 s | 20.800 s | 8.22x | |
| 86 | +| outline/outline | 4.448 s | 55.070 s | 12.38x | |
| 87 | + |
| 88 | +Benchmarks were performed on a MacBook Pro M2 Max 12 Cores (8 performance and 4 efficiency). |
| 89 | + |
| 90 | +Our performance testing shows that `oxlint` with type-aware linting is around 10 times faster than `eslint` with `typescript-eslint`. Take a look at our [performance benchmarks](https://github.com/oxc-project/bench-linter) for more details. |
| 91 | + |
| 92 | +Oxlint can also be used to typecheck your codebase while linting. This avoids a duplicate work, as much of the type information is already computed during type-aware linting. |
| 93 | + |
| 94 | +:::warning Known Issues |
| 95 | +While `tsgolint` is ready for testing in production codebases, you may encounter issues with running out of memory when working with very large codebases. We are working on optimizing the memory usage for the next milestone. We would love if you tried `tsgolint` and reported any out-of-memory issues to us in the [`tsgolint` repository](https://github.com/oxc-project/tsgolint) and included some details about your project to help us improve memory usage. |
| 96 | +::: |
| 97 | + |
| 98 | +## What's new since the technical preview? |
| 99 | + |
| 100 | +### Support for type-checking while linting |
| 101 | + |
| 102 | +`tsgolint` now supports emitting type checking errors from TypeScript while linting. Since type-aware rules already require checking all of the types within a file, we are able to use this existing type information rather than discarding it. This means that in some cases, it is possible to skip doing a separate type-check command altogether (e.g., `tsc --noEmit`), reducing total time spent doing linting and type-checking in CI. |
| 103 | + |
| 104 | +This is an experimental feature, but you can enable it by adding the `--type-check` and `--type-aware` flag to the `oxlint` command: |
| 105 | + |
| 106 | +``` |
| 107 | +$ oxlint --type-aware --type-check |
| 108 | +
|
| 109 | + × typescript(TS2322): Type 'number' is not assignable to type 'string'. |
| 110 | + ╭─[index.ts:1:7] |
| 111 | + 1 │ const message: string = 1 |
| 112 | + · ─────── |
| 113 | + ╰──── |
| 114 | +``` |
| 115 | + |
| 116 | +### Rule configuration support in `oxlint` |
| 117 | + |
| 118 | +Type-aware rules that run in `tsgolint` can be configured in `oxlint` just like any other lint rule. For example, you can configure the `no-floating-promises` rule to allow certain safe calls or ignore `void`: |
| 119 | + |
| 120 | +```json |
| 121 | +{ |
| 122 | + "rules": { |
| 123 | + "typescript/no-floating-promises": [ |
| 124 | + "error", |
| 125 | + { |
| 126 | + "ignoreVoid": true, |
| 127 | + "allowForKnownSafePromises": [ |
| 128 | + { "from": "file", "name": "SafePromise" }, |
| 129 | + { "from": "lib", "name": "PromiseLike" } |
| 130 | + ] |
| 131 | + } |
| 132 | + ] |
| 133 | + } |
| 134 | +} |
| 135 | +``` |
| 136 | + |
| 137 | +The configuration options are aligned with what `typescript-eslint` supports and documentation can be found in the configuration section for each rule (like [`no-floating-promises`](https://oxc.rs/docs/guide/usage/linter/rules/typescript/no-floating-promises.html#configuration)). |
| 138 | + |
| 139 | +### Inline disable comment support in `oxlint` |
| 140 | + |
| 141 | +Rules that run in `tsgolint` can now be disabled similar to any other `oxlint` rule by placing a comment in the file or on a line: |
| 142 | + |
| 143 | +```ts |
| 144 | +/* oxlint-disable typescript/no-floating-promises */ |
| 145 | + |
| 146 | +// oxlint-disable-next-line typescript/no-floating-promises |
| 147 | +[1, 2, 3].map(async (x) => x + 1); |
| 148 | +``` |
| 149 | + |
| 150 | +### More supported rules |
| 151 | + |
| 152 | +We've continued to make progress on porting popular rules from `typescript-eslint` which you can now use via `oxlint`. `tsgolint`, combined with `oxlint`, currently supports 43 type-aware rules. |
| 153 | + |
| 154 | +Since the initial preview, support for the following rules has also been added: |
| 155 | + |
| 156 | +- [`no-deprecated`](/docs/guide/usage/linter/rules/typescript/no-deprecated) (one of the most commonly requested rules) |
| 157 | +- [`prefer-includes`](/docs/guide/usage/linter/rules/typescript/prefer-includes) |
| 158 | +- [`strict-boolean-expressions`](/docs/guide/usage/linter/rules/typescript/strict-boolean-expressions) |
| 159 | + |
| 160 | +### TypeScript program diagnostics are now reported |
| 161 | + |
| 162 | +Previously, if TypeScript failed to create and parse a program, these errors were not reported which led to confusion around why linting was not working. Now, we report any issues with creating a program as a diagnostic, including configuration issues in `tsconfig.json` files. |
| 163 | + |
| 164 | +For example, if a `tsconfig.json` file contains `baseUrl`, that will be reported as an error, since `baseUrl` has been removed from TypeScript in v7.0: |
| 165 | + |
| 166 | +``` |
| 167 | +$ oxlint --type-aware |
| 168 | +
|
| 169 | + × typescript(tsconfig-error): Invalid tsconfig |
| 170 | + ╭─[tsconfig.json:4:3] |
| 171 | + 3 │ "compilerOptions": { |
| 172 | + 4 │ "baseUrl": ".", |
| 173 | + · ───────── |
| 174 | + 5 │ "experimentalDecorators": true, |
| 175 | + ╰──── |
| 176 | + help: Option 'baseUrl' has been removed. Please remove it from your configuration. |
| 177 | + See https://github.com/oxc-project/tsgolint/issues/351 for more information. |
| 178 | +``` |
| 179 | + |
| 180 | +### Automatic fixes for type-aware rules |
| 181 | + |
| 182 | +Type-aware rules now support automatic fixes via the `--fix` flag. When you run `oxlint --type-aware --fix`, fixable diagnostics from `tsgolint` are applied just like regular `oxlint` fixes. This brings full parity with non-type-aware rules for the fix workflow. |
| 183 | + |
| 184 | +## Technical details |
| 185 | + |
| 186 | +### Architecture |
| 187 | + |
| 188 | +Type-aware linting in Oxlint uses a unique two-binary architecture: |
| 189 | + |
| 190 | +``` |
| 191 | +oxlint CLI (Rust) |
| 192 | + ├─ Handles file traversal, ignore logic, and diagnostics |
| 193 | + ├─ Runs non-type-aware rules and custom JS plugins |
| 194 | + ├─ Passes paths and configuration to tsgolint |
| 195 | + └─ Formats and displays results |
| 196 | +
|
| 197 | +tsgolint (Go) |
| 198 | + ├─ Uses typescript-go directly for type checking |
| 199 | + ├─ Executes type-aware rules |
| 200 | + └─ Returns structured diagnostics |
| 201 | +``` |
| 202 | + |
| 203 | +This design keeps Oxlint's core fast while leveraging TypeScript's type system through typescript-go. The frontend-backend separation means `oxlint` controls the user experience while `tsgolint` handles the heavy lifting of type analysis. |
| 204 | + |
| 205 | +### TypeScript compatibility |
| 206 | + |
| 207 | +`tsgolint` is based on [typescript-go](https://github.com/microsoft/typescript-go), Microsoft's Go-based rewrite that will become TypeScript v7.0. For more details on TypeScript 7's progress, see the [official TypeScript blog post](https://devblogs.microsoft.com/typescript/progress-on-typescript-7-december-2025/). This means that you might encounter some features which are no longer supported. |
| 208 | + |
| 209 | +**Important compatibility notes:** |
| 210 | + |
| 211 | +- Only TypeScript 7.0+ features are supported |
| 212 | +- Pre-7.0 syntax and deprecated features are not supported |
| 213 | +- Legacy `tsconfig.json` options like `baseUrl` have been removed in TypeScript 7.0 |
| 214 | + |
| 215 | +If you're using deprecated features from TypeScript 6.0 or earlier, you'll need to migrate your codebase first. See the [TypeScript migration guide](https://github.com/microsoft/TypeScript/issues/62508#issuecomment-3348649259) for help updating deprecated tsconfig options. |
| 216 | + |
| 217 | +### Implementation details |
| 218 | + |
| 219 | +`tsgolint` doesn't use typescript-go's public APIs. Instead, it compiles typescript-go by [shimming](https://github.com/oxc-project/tsgolint/tree/main/shim) internal APIs to make them accessible. We actively track typescript-go updates and fix breaking changes as needed. |
| 220 | + |
| 221 | +Our typescript-go fork is synced regularly using renovatebot, ensuring we stay current with the latest improvements and fixes. Once TypeScript 7.0 is officially released, we will track stable releases rather than the tip of the main branch. |
| 222 | + |
| 223 | +## What's next |
| 224 | + |
| 225 | +We're actively working on the following improvements for the beta release: |
| 226 | + |
| 227 | +- **More supported rules** - Currently we support 43 out of the 59 type-aware rules from `typescript-eslint`. As we head towards a beta release, we plan to continue expanding rule coverage. |
| 228 | +- **Performance and memory usage improvements** - We're going to continue to optimize performance, especially for very large monorepos. |
| 229 | + |
| 230 | +## Acknowledgements |
| 231 | + |
| 232 | +We'd like to extend our gratitude to: |
| 233 | + |
| 234 | +- The TypeScript team for creating `typescript-go`. |
| 235 | +- The `typescript-eslint` team for their heartwarming support. |
| 236 | +- [@auvred](https://github.com/auvred) for creating `tsgolint`. |
| 237 | +- [@camchenry](https://github.com/camchenry) for continued performance work, as well as implementing rule option support. |
| 238 | + |
| 239 | +## Try it out |
| 240 | + |
| 241 | +Ready to get started? Head to the [Quick Start](#quick-start) section above to install and run type-aware linting. |
| 242 | + |
| 243 | +We'd love to hear your feedback on type-aware linting and are excited to see how it helps improve your development workflow. |
| 244 | + |
| 245 | +Connect with us: |
| 246 | + |
| 247 | +- **Discord**: Join our [community server](https://discord.gg/9uXCAwqQZW) for real-time discussions |
| 248 | +- **GitHub**: Share feedback on [GitHub Discussions](https://github.com/oxc-project/oxc/discussions) |
| 249 | +- **Issues**: Report `oxlint` bugs to [oxc](https://github.com/oxc-project/oxc/issues) and type-aware linting bugs to [tsgolint](https://github.com/oxc-project/tsgolint/issues). |
0 commit comments