← Study Notes
🦀 Rust · Frontend Tooling Revolution

The Rust JS Tooling Ecosystem

OXC, Rolldown, Vite, SWC, Turbopack, Biome — the complete picture of why the JavaScript ecosystem is rewriting its tools in Rust (and Go), what each tool does, and what you actually need to care about as a developer.

OXC Rolldown Vite 6 SWC Turbopack Biome esbuild
Section 01

Why is everyone rewriting JS tools in Rust?

JavaScript build tools are bottlenecks. A slow build costs every developer minutes per day, hours per week, and hours per CI run. At scale (monorepos, large teams), this becomes existential. Native languages like Rust and Go eliminate the overhead that comes with running tools on V8.

The fundamental problem with JS-based tooling

JS tools (Babel, Webpack, ESLint)
1. Node.js starts up           (~50–200ms overhead)
2. V8 JIT warms up             (startup cost per run)
3. Read 10,000 .ts files       (synchronous fs in JS)
4. Parse each file             (JS parser in JS = slow)
5. Transform/lint              (single-threaded JS)
6. Bundle output               (more JS, more GC pauses)
7. Write output files

// Result: webpack cold build ~60-180s on large projects
Rust tools (OXC, Rolldown)
1. Native binary starts        (~1ms)
2. Read 10,000 .ts files       (parallel async I/O)
3. Parse each file             (Rust parser, multi-core)
4. Transform/lint              (multi-threaded)
5. Bundle output               (zero GC pauses)
6. Write output files

// Result: OXC parses 3x faster than esbuild (Go)
//         Rolldown full build in seconds

Why Rust specifically (not just C++)?

  • Memory safety without GC: No garbage collector pauses, no segfaults, no data races — enforced at compile time (same ownership system from the Rust guide)
  • Fearless concurrency: Parse 10,000 files in parallel across all CPU cores with no data race bugs
  • C-level speed: Benchmarks show Rust tools often faster than equivalent C++ due to better optimization hints
  • Interop with JS: napi-rs and wasm-bindgen make it easy to call Rust from Node.js or the browser
  • Great ecosystem: crates for parsing, async I/O (tokio), WASM output
🦀
Go vs Rust: esbuild (written in Go) proved native tools could be 10-100× faster than JS tools. Rust tools are now benchmarking 2-5× faster than esbuild itself. Go is faster to write; Rust is faster to run.
Section 02

Ecosystem Map — Old vs New

Every JS/TS build tool and its native replacement.

Babel (JS)
SWC (Rust)
Used by Next.js, Parcel, Jest
ts-node (JS)
tsx / bun (Rust/Zig)
Run .ts files directly
webpack (JS)
Turbopack (Rust)
Next.js dev server (--turbo)
Rollup (JS)
Rolldown (Rust)
Vite 6 production builds
esbuild (Go)
Rolldown (Rust)
Replaces esbuild in Vite dev too
ESLint (JS)
Oxlint (Rust / OXC)
50–100× faster, ESLint compatible
ESLint (JS)
Biome (Rust)
Linter + formatter, standalone
Prettier (JS)
Biome (Rust)
25× faster than Prettier
Acorn/Babel parser (JS)
OXC parser (Rust)
3× faster than esbuild's Go parser
Jest (JS)
Vitest (uses esbuild)
Vite-native, faster than Jest
Section 03

How We Got Here — Timeline

2012–2016
The JS-tools era: Grunt → Gulp → webpack → Babel
All build tools written in JavaScript/Node.js. Fast to develop, slow to run. webpack builds take 30–180 seconds on large projects.
2020
esbuild (Go) shocks the ecosystem
Evan Wallace releases esbuild — a bundler written in Go. 10–100× faster than webpack. Proves native languages are viable. Vite adopts it for dep pre-bundling.
2021
SWC goes mainstream · Vite 2 launches
Next.js replaces Babel with SWC (Rust). 17× faster compilation. Vite 2 gains massive adoption. Vercel announces Turbopack research.
2022
Turbopack announced · Rome → Biome
Vercel ships Turbopack (Rust, by webpack creator Sebastian McKenzie). Rome project rebrands as Biome (Rust formatter+linter). Rust tooling race accelerates.
2023
OXC launched · Rolldown begins
Boshen Chen announces OXC (Oxidation Compiler) — Rust parser for JS/TS, 3× faster than esbuild. Evan You (Vue/Vite creator) announces Rolldown will replace Rollup in Vite.
2024
Rolldown goes public · Oxlint ships · Vite 6
Rolldown reaches public beta. Oxlint (linter on OXC) ships. Vite 6 begins integrating Rolldown. Biome reaches stable v1. The Rust toolchain becomes real.
2025–2026
Consolidation — Rust stack becomes default
Vite + Rolldown is the standard frontend build setup. SWC powers all Next.js projects. Turbopack ships stable for Next.js. Teams run Oxlint alongside (or instead of) ESLint.
Section 04

OXC — The Oxidation Compiler Rust

OXC is a collection of high-performance Rust tools for JavaScript and TypeScript built on a shared parser. Think of it as the "foundation layer" — Rolldown is built on OXC, Oxlint is built on OXC.

OXC components

oxc_parser
JS/TS/JSX parser
Parses JavaScript and TypeScript into an AST. 3× faster than esbuild's Go parser. Foundation for all other OXC tools.
Oxlint
Linter (ESLint replacement)
50–100× faster than ESLint. Supports 400+ ESLint rules. Can run alongside ESLint for a speed boost on basic rules.
oxc_transformer
Code transformer
Replaces Babel transforms. TypeScript stripping, JSX → JS, class properties, decorators — all without Babel.
oxc_minifier
JS minifier
Replaces terser/esbuild minifier. Compresses JS output for production.
oxc_resolver
Module resolver
Implements Node.js + bundler module resolution. Used by Rolldown to resolve imports.
Oxlint Fastest ESLint alternative
# Install oxlint
npm install -D oxlint

# Run on your project (no config required)
npx oxlint src/

# With config
# oxlintrc.json
{
  "rules": {
    "no-unused-vars": "error",
    "no-console": "warn"
  }
}

# Recommended: run oxlint FIRST (fast), then ESLint for complex rules
# "lint:fast": "oxlint src/",
# "lint": "oxlint src/ && eslint src/"
💡
Migration strategy: Don't replace ESLint with Oxlint overnight. Add Oxlint for a fast "first pass" on common rules, keep ESLint for complex plugin rules (typescript-eslint, react hooks, etc.). As Oxlint adds more rules, you can drop ESLint gradually.
Section 05

Rolldown Rust

Rolldown is a Rust bundler with a Rollup-compatible plugin API. It's the centerpiece of the "VoidZero" initiative (Evan You's company to build a unified JS toolchain). Rolldown replaces both esbuild and Rollup inside Vite.

Rolldown vs Rollup vs esbuild

Feature Rollup JS esbuild Go Rolldown Rust
SpeedSlowVery fastFastest
Tree-shakingExcellentGoodExcellent (Rollup model)
Plugin ecosystemHuge (Rollup plugins)LimitedRollup-compatible ✅
Code splittingYesYesYes
CJS outputYesYesYes
ESM outputYesYesYes
Dev serverNoVia ViteVia Vite (replaces esbuild here)
LanguageJavaScriptGoRust (built on OXC)

Key architectural insight

Rolldown doesn't just replicate Rollup's output — it uses the same mental model (entry → chunks → tree-shaken output) but implements it in Rust with OXC as the parser. Your existing Vite/Rollup plugins continue to work because Rolldown exposes the same hook API.

Rolldown Plugin API (Rollup-compatible)
// A Rolldown plugin looks identical to a Rollup plugin
import { defineConfig } from 'rolldown'; // or 'rollup'

export default defineConfig({
  input: './src/index.ts',
  output: { dir: 'dist', format: 'esm' },
  plugins: [
    {
      name: 'my-plugin',
      // Same hooks as Rollup
      transform(code, id) {
        if (!id.endsWith('.ts')) return;
        // transform TypeScript...
        return { code: transformed };
      },
      resolveId(source) { /* ... */ },
      load(id)         { /* ... */ },
      generateBundle(options, bundle) { /* ... */ },
    }
  ]
});
Section 06

Vite's Evolution Vite 6+

Vite is the most important frontend build tool. Understanding how it's changing helps you understand why Rolldown and OXC matter.

Vite before (dual-bundler problem)

Vite 4/5 Two bundlers, two behaviors
┌────────────────────────────────────────────────────────┐
│  vite dev                                              │
│  └─ esbuild (Go) — pre-bundles node_modules deps       │
│  └─ Native ESM  — serves your source files as-is      │
│                                                        │
│  vite build                                            │
│  └─ Rollup (JS) — bundles everything for production   │
│                                                        │
│  Problem: dev uses esbuild, prod uses Rollup           │
│  → subtle differences in output, hard to debug         │
│  → two plugin systems to maintain                      │
└────────────────────────────────────────────────────────┘

Vite after Rolldown

Vite 6+ Single bundler
┌────────────────────────────────────────────────────────┐
│  vite dev                                              │
│  └─ Rolldown (Rust) — pre-bundles + serves            │
│                                                        │
│  vite build                                            │
│  └─ Rolldown (Rust) — same bundler, same output       │
│                                                        │
│  Benefits:                                             │
│  ✅ Dev and prod behavior identical                    │
│  ✅ One plugin to rule both                            │
│  ✅ Rust speed for production builds                   │
│  ✅ Existing Rollup plugins still work                 │
└────────────────────────────────────────────────────────┘
ℹ️
For you as a Vite user: You don't need to do anything. Update to Vite 6, your builds get faster, dev/prod parity improves. Your existing plugins keep working. Rolldown is an implementation detail.
Section 07

SWC — Speedy Web Compiler Rust

SWC is a Rust-based JavaScript/TypeScript compiler. Its job: take .ts / .tsx source and output JavaScript — the same job Babel did, but 17× faster. It does not type-check (that's still tsc's job).

SWC vs Babel

Babel (JS)
// .babelrc
{
  "presets": [
    "@babel/preset-typescript",
    "@babel/preset-react",
    ["@babel/preset-env", {
      "targets": "defaults"
    }]
  ]
}

// Speed: ~2s for 1000 files
// Plugins: huge ecosystem
// Type checking: ❌ separate tsc step
SWC (Rust)
// .swcrc
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true
    },
    "transform": {
      "react": { "runtime": "automatic" }
    },
    "target": "es2022"
  }
}

// Speed: ~0.1s for 1000 files (17x faster)
// Type checking: ❌ still need tsc --noEmit

Where SWC is used

  • Next.js: Replaces Babel since Next.js 12. You don't configure it — Next does automatically.
  • Parcel 2: Uses SWC as its transformer.
  • Jest / Vitest: @swc/jest transforms test files faster than Babel-jest.
  • SWC CLI: Use standalone to transpile TS→JS scripts.
SWC Replace Babel in Jest
# Install
npm install -D @swc/core @swc/jest

# jest.config.ts
export default {
  transform: {
    '^.+\\.(t|j)sx?$': ['@swc/jest']
  }
}

# Result: Jest startup 3-5× faster
Section 08

Turbopack Rust

Turbopack is Vercel's Rust-based incremental bundler, built by Tobias Koppers (webpack's creator) and the Next.js team. It powers the Next.js dev server. Unlike Rolldown (which replaces Rollup), Turbopack is designed to replace webpack.

The key word: incremental

Turbopack's architecture is fundamentally different from traditional bundlers. It uses a demand-driven computation graph — it only computes what you asked for and caches everything aggressively.

Turbopack How to enable in Next.js
# Dev server with Turbopack (stable in Next.js 15)
next dev --turbopack
# or in package.json:
{ "dev": "next dev --turbopack" }

# next.config.ts
const nextConfig = {
  experimental: {
    turbopack: {
      rules: {
        // custom rules
      }
    }
  }
}

# Speed on large apps:
# Cold start: ~700ms vs webpack's ~8s
# HMR update: ~10ms vs webpack's ~200ms

Turbopack vs Rolldown

TurbopackRolldown
Made byVercelVoidZero (Evan You)
Replaceswebpack (dev)Rollup + esbuild
Used inNext.jsVite 6
Plugin APICustom (webpack-inspired)Rollup-compatible
Production buildsNot yet (planned)Yes
IncrementalYes (core design)Partial
FrameworkNext.js onlyVite ecosystem
Section 09

Biome Rust

Biome (formerly Rome) is an all-in-one Rust tool that replaces Prettier (formatter) and ESLint (linter) with a single binary. 97% Prettier-compatible formatting, 25× faster.

Biome vs Prettier + ESLint

Old setup (JS)
# 3 tools, 3 configs, 3 package installs
npm install -D \
  prettier \
  eslint \
  @typescript-eslint/eslint-plugin \
  @typescript-eslint/parser \
  eslint-config-prettier   # prevent conflicts!

# .eslintrc.json
# .prettierrc
# .eslintignore
# .prettierignore
# Scripts in package.json for each
Biome (Rust)
# 1 tool, 1 config
npm install -D @biomejs/biome

# biome.json
{
  "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
  "organizeImports": { "enabled": true },
  "linter": {
    "enabled": true,
    "rules": { "recommended": true }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2
  }
}
Biome Common commands
# Format all files
npx biome format --write .

# Lint all files
npx biome lint .

# Format + lint + fix in one pass
npx biome check --write .

# CI (fail on issues, don't fix)
npx biome ci .

# VS Code: install "Biome" extension and set as default formatter

Biome vs Oxlint

BiomeOxlint
FormattingYes (replaces Prettier)No
LintingYes (replaces ESLint)Yes
ESLint plugin compatNoPartial
Import sortingYesNo
Config complexitySimple (one file)Simple
Use with ESLintCan coexistDesigned to complement
Best forReplace Prettier + ESLint entirelySpeed up ESLint-heavy setups
Section 10

esbuild Go — The Pioneer

esbuild isn't Rust, but it started the native-speed tooling revolution. Written in Go by Evan Wallace, it proved that JS tooling could be 10–100× faster. Vite currently uses it for dep pre-bundling and TypeScript transpilation.

What esbuild does

  • Bundles JS/TS (fast, but less flexible than Rollup — no circular dep analysis, simpler tree-shaking)
  • Transpiles TypeScript → JavaScript (strips types only, no type checking)
  • Minifies JS/CSS
  • Used by: Vite (internally), many CLIs for fast builds

esbuild's limits (why Rolldown still matters)

  • Limited plugin API — can't replicate the full Rollup plugin ecosystem
  • No advanced code splitting strategies
  • No CSS Modules support natively
  • No import.meta awareness at the level Rollup has
  • Hard to extend for complex use cases
ℹ️
esbuild's future with Vite: When Vite fully migrates to Rolldown, esbuild's role shrinks. Rolldown handles both what esbuild and Rollup did, and it's faster. esbuild still lives on as a standalone tool and in non-Vite projects.
Section 11

Speed Benchmarks

Relative speeds across key operations (all numbers approximate, hardware-dependent).

Parser throughput (lines/second)

OXC (Rust)
~4M lines/s
esbuild (Go)
~1.3M lines/s
swc (Rust)
~1M lines/s
Babel (JS)
~200K/s

Linting (1000 files)

Oxlint (Rust)
~0.05s
Biome (Rust)
~0.08s
ESLint (JS)
~5s

Format 500 files

Biome (Rust)
~0.04s
Prettier (JS)
~1s
Section 12

What Replaces What

Old tool Language New tool Language Used in Action needed
BabelJS SWCRust Next.js (auto), Jest None for Next.js. Update Jest config.
RollupJS RolldownRust Vite 6 Update Vite. Plugins keep working.
esbuild (in Vite)Go RolldownRust Vite 6 None — Vite handles it.
webpackJS TurbopackRust Next.js --turbopack Add --turbopack flag.
PrettierJS BiomeRust Any project Install Biome, delete Prettier config.
ESLintJS Oxlint + BiomeRust Any project Gradual: add Oxlint alongside ESLint first.
ts-nodeJS tsx / bunRust/Zig Scripts, CLI Replace ts-node script.ts with bun script.ts.
Section 13

What You Actually Need to Know

Most of this is infrastructure. You don't configure OXC, Rolldown, or Turbopack directly. Here's what actually matters for your day-to-day work.

If you use Next.js

  • SWC is already active — Babel is gone. You don't need to do anything.
  • Run next dev --turbopack for a faster dev server (stable in Next.js 15).
  • Some Babel plugins don't have SWC equivalents — check your config if you use unusual Babel transforms.

If you use Vite

  • Vite 6 brings Rolldown — update and your builds get faster automatically.
  • Your existing Vite/Rollup plugins keep working (Rolldown is Rollup-compatible).
  • Dev/prod parity improves — fewer "works in dev but not in prod" bugs.

Things to actively adopt today

  • Biome: Drop Prettier + ESLint for new projects. One config, much faster.
  • Oxlint: Add to existing projects alongside ESLint for fast basic checks.
  • bun: Use as your package manager and for running TS scripts directly.
🎯
Priority order for adopting Rust tooling:
  1. Enable --turbopack in Next.js (Next.js 15, one flag)
  2. Add Biome to new projects (replaces Prettier + ESLint)
  3. Use bun for installs and TS scripts
  4. Add Oxlint to existing projects for faster lint CI step
  5. Update Vite → get Rolldown for free
Section 14

Setting Up Each Tool

Biome — replace Prettier + ESLint

Biome Complete setup
# Install
npm install -D @biomejs/biome

# Initialize config
npx biome init

# Migrate from Prettier (imports settings)
npx biome migrate prettier --write
npx biome migrate eslint --write

# package.json scripts
{
  "scripts": {
    "format": "biome format --write .",
    "lint":   "biome lint .",
    "check":  "biome check --write .",
    "ci":     "biome ci ."
  }
}

# VS Code: install "Biome" extension
# Set as default formatter: Cmd+Shift+P → Preferences: Default Formatter → Biome

Oxlint — alongside ESLint

Oxlint Complement ESLint
# Install
npm install -D oxlint

# package.json — run oxlint first (fast), then ESLint for complex rules
{
  "scripts": {
    "lint": "oxlint . && eslint ."
  }
}

# To avoid duplicate rules, disable ESLint rules that oxlint covers:
# eslint-plugin-oxlint does this automatically
npm install -D eslint-plugin-oxlint

SWC with Jest

SWC Jest transformer
# Install
npm install -D @swc/core @swc/jest

# jest.config.ts
export default {
  transform: {
    '^.+\\.(t|j)sx?$': ['@swc/jest', {
      jsc: {
        parser: { syntax: 'typescript', tsx: true },
        transform: { react: { runtime: 'automatic' } }
      }
    }]
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx']
};
Section 15

Decision Guide

GoalToolEffort
Faster Next.js dev servernext dev --turbopackOne flag
Faster Vite buildsUpdate to Vite 6npm update vite
Replace Babel in Jest@swc/jestLow — update jest.config
Replace PrettierBiomeLow — one config file
Replace Prettier + ESLintBiomeMedium — migrate rules
Speed up ESLint in CIOxlintLow — add one script
Run TypeScript scriptsbun or tsxInstall and use
New project from scratchVite + Biome + pnpm + bunLow — all work together
🦀
The big picture: You don't choose between "JS tools" and "Rust tools." The Rust tools are being embedded into frameworks (Vite, Next.js) — you get them automatically. The ones you actively adopt (Biome, Oxlint, bun) are simple, drop-in replacements with clear setup guides.