Fast linting. Familiar rules.

A fast JavaScript and TypeScript linter, built in Zig.

bash
ut install -D @utoo/lint

Native at the core

Built in Zig, with Yuku parsing and semantic analysis. Lint files in parallel using prebuilt binaries for macOS, Linux, and Windows.

Made for real projects

JavaScript, TypeScript, React, accessibility, and import rules. Use familiar rule IDs and severities, with safe autofix where supported.

Ready for your workflow

Typed or JSON configuration, suppression comments, and JSON diagnostics. Use the CLI, JavaScript API, or in-memory WebAssembly package.

index.tsTypeScript
Autofix example
typescript
function greet(name: string) {
let message = `Hello, ${name}`;;
const messages = new Array(message, 'Welcome');
return { messages: messages };
}
4 diagnostics with safe autofixes
PERFORMANCE

More feedback. Less waiting.

The same TypeScript corpus. The same 12 shared rules. Every sample starts a fresh CLI process, including startup time.

9.52msutoo-lint median
78.0×faster than ESLint in this run
Read the recorded results
100 TypeScript files · 12 shared rules

Every millisecond counts.

Shorter is faster
Median CLI timems
Select a tool to explore its runsLinear scale from zero
utoo-lintFastest20 measured runs
Run 1: 9.981 msRun 2: 9.872 msRun 3: 9.946 msRun 4: 11.041 msRun 5: 9.486 msRun 6: 9.776 msRun 7: 9.509 msRun 8: 9.375 msRun 9: 9.636 msRun 10: 9.330 msRun 11: 9.331 msRun 12: 9.447 msRun 13: 9.522 msRun 14: 9.211 msRun 15: 9.572 msRun 16: 9.403 msRun 17: 9.274 msRun 18: 9.259 msRun 19: 9.808 msRun 20: 10.049 ms
Observed range9.21–11.04ms
Recorded Aug 30, 2026 · macOS arm64 · Node.js 20.19.1 · 5 warmups per tool.Save chart

A recorded run on one generated workload. Results vary with hardware, code, and enabled rules. The archived report documents the environment and comparison limits.

CONFIGURATION

Your rules. In your language.

Start with the frontend preset, then adapt it to your project. Typed configuration brings editor completion; static JSON works when you need a data-only config.

  • ESLint-style rule names and severities
  • File patterns, global ignores, and flat config arrays
  • Presets you can extend and override
Explore configuration
utlint.config.tsTypeScript
typescript
import { defineConfig } from '@utoo/lint/config';
import frontend from '@utoo/lint/configs/frontend';
export default defineConfig({
...frontend,
rules: {
...frontend.rules,
'no-console': 'warn',
},
});
ADOPTION

Start small. Migrate with confidence.

Bring over supported rules at your own pace. The migration report shows what can move and what still needs ESLint.

  1. Inspect your config

    Preview the migration before writing files. Review the report for unsupported options and plugin behavior.

    utoo-lint migrate eslint --print
  2. Move supported rules

    Check coverage for the rules your project uses. Keep unsupported processors, custom plugins, and type-service workflows in ESLint.

    Check rule coverage →
  3. Verify in your project

    Run both tools in CI and compare diagnostics. Remove duplicate ESLint coverage as each rule is verified.

    Read the migration guide →
ONE ENGINE, MULTIPLE RUNTIMES

From your repository to the browser.

Native CLI

Lint your source tree and apply supported fixes, locally or in CI.

pnpm exec utoo-lint srcUse the CLI →

WebAssembly

Lint and fix one in-memory file. The Playground processes code locally in your browser.

@utoo/lint-wasmExplore WebAssembly →
Last updated: