Skip to main content

Rise of Rust in JavaScript Tooling 2026

·PkgPulse Team
0

TL;DR

Rust ate the JavaScript tooling stack. Every major performance bottleneck in JS development — parsing, transpilation, bundling, linting, formatting — now has a Rust-powered alternative that's 10-100x faster. SWC (~20M weekly downloads) replaced Babel. Biome (~2M) is replacing ESLint+Prettier. Rspack (~2M) is Webpack in Rust. Turbopack is Next.js's Rust bundler. Oxc is a comprehensive Rust-based JS toolchain. The pattern: write your app in JavaScript/TypeScript; run tools written in Rust.

Key Takeaways

  • SWC: ~20M weekly downloads — Rust transpiler, powers Next.js, Deno, Parcel
  • Turbopack: ~8M downloads — Rust bundler (Next.js), 5-10x faster than Webpack
  • Rspack: ~2M downloads — Webpack-compatible Rust bundler from ByteDance
  • Biome: ~2M downloads — Rust linter + formatter, 100x faster than ESLint+Prettier
  • Oxc: growing fast — comprehensive Rust JS toolchain (parser, linter, transformer)

Why Rust Won JavaScript Tooling

The Performance Gap Was Unsustainable

JavaScript-based tools (2020):
- Babel transpile 1000 files: ~8 seconds
- ESLint scan codebase: ~8 seconds
- Webpack build (500 components): ~50 seconds
- Prettier format 1000 files: ~3 seconds

Rust-based equivalents (2026):
- SWC transpile 1000 files: ~0.2 seconds  (40x faster)
- Biome scan codebase: ~0.08 seconds      (100x faster)
- Turbopack build (500 components): ~5s   (10x faster)
- Biome format 1000 files: ~0.1 seconds  (30x faster)

As codebases grew from hundreds to thousands of files, JS-based tools hit a wall. A 30-second lint step doesn't fit in a tight feedback loop.

Why Rust Specifically

  1. No garbage collector — Rust's ownership model avoids GC pauses that plague Java/Go tooling
  2. True parallelism — Rust can safely parallelize across all CPU cores; JS is single-threaded
  3. Memory efficiency — Rust allocates exactly what it needs; JS runtimes have overhead
  4. WASM compatibility — Rust tools compile to WebAssembly for browser/Node embedding
  5. Existing ecosystem — Rust's napi-rs and neon make Node.js native addons easy

SWC (The Babel Killer)

// .swcrc — SWC configuration
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": true
    },
    "transform": {
      "react": {
        "runtime": "automatic",
        "refresh": true          // Fast Refresh support
      }
    },
    "target": "es2022",
    "loose": false
  },
  "module": {
    "type": "es6"
  }
}
# SWC direct usage
npx @swc/cli compile src/ -d dist/ --source-maps

# Build time comparison (1000 TypeScript files):
# Babel:  ~8.2s
# SWC:    ~0.18s  (45x faster)
# esbuild: ~0.15s (similar, different approach)

SWC is used internally by:

  • Next.js (replaced Babel in Next.js 12)
  • Deno (for TypeScript compilation)
  • Parcel (as a transformer)
  • Vitest (as a transformer option)
  • Vercel (build infrastructure)

Turbopack (The Webpack Successor)

// Turbopack is transparent to Next.js users
// It's the default bundler in Next.js 15

// next.config.js — no Turbopack config needed
/** @type {import('next').NextConfig} */
export default {};  // Turbopack handles everything

// If you need Turbopack-specific config:
export default {
  experimental: {
    turbo: {
      resolveAlias: {
        '@/components': './src/components',
      },
      rules: {
        '*.svg': {
          loaders: ['@svgr/webpack'],
          as: '*.js',
        },
      },
    },
  },
};
# Turbopack benchmarks (Vercel's test suite, large Next.js app)
# First compile:           ~800ms  (vs Webpack: ~10,000ms)
# HMR (small change):     ~60ms   (vs Webpack: ~2,000ms)
# HMR (large change):     ~200ms  (vs Webpack: ~5,000ms)

Rspack (Webpack Compatible, Rust-Powered)

// rspack.config.js — drop-in Webpack replacement
const path = require('path');

/** @type {import('@rspack/core').Configuration} */
module.exports = {
  entry: './src/index.ts',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'builtin:swc-loader',  // Built-in SWC (no extra package)
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],  // Webpack loaders work!
      },
    ],
  },
  resolve: { extensions: ['.ts', '.tsx', '.js'] },
};
# Rspack is designed for Webpack migration
# Most Webpack configs work with minimal changes

# Build comparison (500 component React app):
# Webpack 5:  ~35s cold build
# Rspack:     ~4s  cold build  (8x faster)
# Vite:       ~8s  cold build
# Turbopack:  ~3s  cold build

# Who should use Rspack:
# - Large Webpack apps that can't easily migrate to Vite
# - Teams using Webpack-specific loaders/plugins
# - ByteDance open-sourced this; battle-tested at TikTok scale

Biome (ESLint + Prettier in Rust)

// biome.json — one config replaces .eslintrc + .prettierrc
{
  "$schema": "https://biomejs.dev/schemas/1.5.0/schema.json",
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "lineWidth": 100
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  }
}
# Biome speed on a 1000-file TypeScript monorepo:
# ESLint + Prettier: ~12 seconds
# Biome:            ~0.15 seconds  (80x faster)

# The Biome trade-off:
# ✅ Unified config, blazing fast, actively maintained
# ⚠️ Fewer rules than ESLint (no eslint-plugin-react-hooks yet in 2026)
# ⚠️ Newer — some teams wait for rule parity

# Migration from ESLint: ~2-4 hours for medium codebase
# Migration from Prettier: ~30 minutes

Oxc (The Comprehensive Toolchain)

Oxc (Oxidation Compiler) is the newest entrant — a comprehensive Rust-based JavaScript/TypeScript toolchain aiming to replace multiple tools at once:

# Oxc components:
# oxc_parser    — fastest JS/TS parser (3x faster than SWC parser)
# oxlint        — linter (50-100x faster than ESLint)
# oxc_transform — transformer (competing with SWC)
# rolldown      — Rollup-compatible Rust bundler (powers Vite's future)

# oxlint — try it now
npx oxlint@latest src/

# Comparison on 500 TypeScript files:
# ESLint:  ~5,000ms
# Biome:   ~80ms
# oxlint:  ~50ms   (100x faster than ESLint)

Rolldown (Rust port of Rollup, built by the Vite team) is particularly significant — it's the future production bundler for Vite 6, giving Vite the same Rust speed advantage for production builds that it already has in dev (via esbuild).


The Rust Tooling Map

Transpilation:    Babel → SWC (done)
Formatting:       Prettier → Biome (in progress, ~60% adoption for new projects)
Linting:          ESLint → Biome / oxlint (in progress, ~40% for new projects)
Bundling (app):   Webpack → Turbopack / Rspack / Vite (in progress)
Bundling (lib):   Rollup → Rolldown (coming in Vite 6)
Type checking:    tsc → ? (no Rust replacement yet — tsc remains the authority)

The one thing Rust can't replace: TypeScript's type checker. The type system is complex enough that a Rust reimplementation doesn't exist yet (though teams like Speedy Web Compiler explored it). tsc --noEmit remains the gold standard for type checking in 2026.


When to Choose Rust Tools

ScenarioRust Tool
New Next.js projectTurbopack (default)
Migrating from Webpack (can't use Vite)Rspack
Replacing Babel in custom setupSWC
Replacing ESLint + PrettierBiome
Fastest possible linting in CIoxlint
Publishing npm librarytsup (uses esbuild/Rollup, transitioning to Rolldown)
Framework-specific lint rules neededKeep ESLint + add Biome for formatting

The Rust tooling transition is ongoing and has not yet reached an endpoint. SWC's adoption is effectively complete — almost every major framework uses it for transpilation. Biome adoption for formatting is at roughly 60% of new projects and rising, but ESLint retains dominance for linting because of its plugin ecosystem. Rspack adoption is accelerating among teams migrating from Webpack who cannot easily switch to Vite. The remaining frontier is production bundling: Rolldown (the Rust Rollup port) is expected to become Vite's production bundler in version 6, completing Rust's takeover of the hot-path tooling layer. The one gap that remains resistant — TypeScript type checking — reflects the genuine complexity of replicating TypeScript's type system, not a lack of engineering effort.

Compare Rust-based tooling package health on PkgPulse.

See also: Turbopack vs Vite and Rspack vs webpack, Why Developers Are Moving to Rust-Based Tools.

Migrating to Rust-Based Tools: A Practical Guide

The performance case is clear, but migration carries risk. Here's how to approach each tool switch safely.

Babel → SWC

SWC is the most mature migration and has the lowest risk. Next.js, Parcel, and Vite already use it internally, so most developers already run their code through SWC without realizing it. For direct usage:

npm install -D @swc/core @swc/cli

# Replace babel-loader in Webpack with swc-loader
npm install -D swc-loader
// webpack.config.js — replace babel-loader
module.exports = {
  module: {
    rules: [{
      test: /\.(ts|tsx)$/,
      use: 'swc-loader',  // was: 'babel-loader'
      exclude: /node_modules/,
    }],
  },
};

The main gap: Babel plugins. If your project uses custom Babel plugins (styled-components, emotion, or decorators-heavy frameworks), check whether SWC equivalents exist before migrating. Most popular Babel transforms have SWC equivalents, but niche plugins may not.

Effort: Low (1-4 hours for most projects). Risk: Low.

ESLint + Prettier → Biome

This migration has the most visible day-to-day impact — you eliminate a config file, a dependency, and cut lint/format times by 30-100x. The practical trade-off is rule parity.

# Install Biome
npm install -D --save-exact @biomejs/biome

# Migrate from Prettier (auto-generates biome.json)
npx @biomejs/biome migrate prettier --write

# Migrate from ESLint
npx @biomejs/biome migrate eslint --write

The migration commands read your existing .eslintrc and .prettierrc and generate an equivalent biome.json. Not all ESLint rules have Biome equivalents — the migration report shows which rules are missing. For missing rules, you have three options: accept the gap, keep ESLint for just those rules, or open a Biome issue (the team is actively filling gaps).

Rules that commonly don't have Biome equivalents in 2026: framework-specific plugins (eslint-plugin-react-hooks is partially supported, eslint-plugin-next is not). If you rely heavily on framework-specific rules, a hybrid setup works:

// Use Biome for formatting + general linting, ESLint for framework rules
// package.json scripts
{
  "lint": "biome check . && eslint src --rule 'react-hooks/rules-of-hooks: error'",
  "format": "biome format --write ."
}

Effort: Medium (2-8 hours). Risk: Medium (rule parity gaps).

Webpack → Rspack

Rspack is explicitly designed for this migration. Its configuration format is intentionally identical to Webpack 5.

npm install -D @rspack/core @rspack/cli
// rspack.config.js — paste your webpack.config.js, change the require
const { rspack } = require('@rspack/core');  // was: const webpack = require('webpack')

module.exports = {
  // Your exact Webpack config — most of it works unchanged
  plugins: [
    new rspack.HtmlRspackPlugin({ template: './public/index.html' }),  // was HtmlWebpackPlugin
  ],
};

The main compatibility gaps in 2026: some advanced Webpack plugins (especially those that tap deep into Webpack's compilation hooks) may not have Rspack equivalents. Check rspack.dev/guide/compatibility for the current compatibility matrix.

Effort: Low to Medium (2-16 hours depending on plugin usage). Risk: Low for standard configs, Medium for custom plugins.

Common Mistakes When Adopting Rust Tools

Expecting configuration parity on day one. Rust tools are newer and deliberately prioritize the 80% case. Biome doesn't have every ESLint rule. Rspack doesn't support every Webpack plugin. Teams that try to achieve 100% configuration parity before switching will never switch. Instead, accept the gaps, document what's missing, and proceed. You can always maintain a hybrid setup temporarily.

Forgetting that speed gains are relative to your pain. If your current lint step takes 2 seconds, switching to Biome for a 0.5-second improvement won't change your workflow. The biggest wins come from large codebases where JS-based tools genuinely hurt. A monorepo with 50,000 lines of TypeScript going from a 15-second lint step to 0.2 seconds is transformative. A 5,000-line app going from 1 second to 0.1 seconds is barely noticeable.

Running Rust tools on every file every time. The performance wins are largest when you run tools in watch mode or on changed files only. CI pipelines that run biome check on the entire codebase every PR still benefit from the speed, but the real DX improvement is local watch mode. Configure your editor extension (Biome has VS Code and JetBrains extensions) for real-time feedback.

Assuming WASM builds match native performance. When Rust tools publish WebAssembly builds for use in the browser or in non-native environments, they're slower than the native binary — typically 3-5x slower. This is still usually faster than the JavaScript equivalents, but don't benchmark WASM builds and expect native performance. The native CLI is always faster.

The One Gap Rust Can't Close: Type Checking

It's worth addressing directly: no Rust-based tool replaces TypeScript's type checker, and there's no clear timeline for when one will. The TypeScript type system is complex enough — with conditional types, mapped types, infer, template literal types, and declaration merging — that a correct Rust reimplementation would be a multi-year effort.

What this means practically: tsc --noEmit remains a required step in your CI pipeline regardless of which Rust tools you adopt. The typical modern setup:

# CI pipeline
bun run biome check .           # ~0.2s — lint + format
bun run tsc --noEmit            # ~8s  — type check (still TypeScript)
bun run vitest run              # ~15s — tests
bun run vite build              # ~8s  — production build (Rollup/Rolldown)

# Total: ~31s (was: ~120s with all-JS tooling)

The Speedy TypeScript (STC) project and Microsoft's own investigation into a Go-based type checker have both explored alternatives, but as of 2026, tsc remains the only reliable type checker. Oxc's transformer can strip types for transpilation without checking them — but stripping types is not the same as checking them.

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.