Back

Do bundler ao linter, tudo tá sendo reescrito em Rust

Se você acompanha o mundo frontend, já deve ter percebido: bundler, linter, transpilador, minificador... tudo tá sendo reescrito em Rust, um atrás do outro.

E não é 20% mais rápido. É 10x a 100x.

Rolldown bateu 1.0 RC e já é o bundler padrão do Vite 8 beta. Oxlint tá 50-100x na frente do ESLint. Rspack 2.0 Preview sai esse mês.

Se você ainda tá no Webpack, é hora de prestar atenção.


Por que Rust?

Ferramentas JS têm um problema estrutural

Para e pensa: JavaScript foi feito pro browser. Usar ele pra compilar milhares de arquivos numa thread só, com garbage collector no meio... é gargalo garantido.

Quando você roda npm run build, o que acontece por baixo:

  1. Babel parseia pra AST → transforma → serializa
  2. ESLint parseia o mesmo código em outra AST → checa regras
  3. Webpack/Rollup parseia de novo → resolve módulos → bundlea
  4. Terser parseia o resultado → comprime

O mesmo código parseado 4+ vezes, com 4 formatos de AST, tudo single-threaded, com pause de GC. Não faz sentido nenhum.

O que muda com Rust

ProblemaJavaScriptRust
VelocidadeJIT, overhead do V8Binário nativo, zero-cost abstractions
MemóriaGC com pausas imprevisíveisOwnership model, sem GC
ParalelismoWorker threads com custo de serializaçãoMulti-threading nativo
ParseCada ferramenta cria sua ASTUma AST só compartilhada

Resultado: build de 30s cai pra 2s. Linting de 10s pra 0.1s. Números reais, não benchmark sintético.


Quem tá fazendo o quê

┌─────────────────────────────────────────────────────────────┐
│                     VoidZero (Evan You)                       │
│              Toolchain JS unificado em Rust                  │
│                                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌─────────────┐ │
│  │   Vite   │  │ Rolldown │  │   Oxc    │  │   Vitest    │ │
│  │ Dev Svr  │  │ Bundler  │  │ Parser   │  │ Test Runner │ │
│  │          │  │          │  │ Linter   │  │             │ │
│  │          │  │          │  │ Minifier │  │             │ │
│  └──────────┘  └──────────┘  └──────────┘  └─────────────┘ │
└─────────────────────────────────────────────────────────────┘

┌──────────────────────┐  ┌──────────────────────┐
│  Rspack (ByteDance)  │  │  Biome (Comunidade)  │
│  Compatível Webpack  │  │  Formatter + Linter  │
└──────────────────────┘  └──────────────────────┘

No centro de tudo tá a VoidZero, empresa do Evan You (criador do Vue.js e Vite). A ideia é simples: "Pra que cada ferramenta parseia o código separado? Uma vez basta."


Rolldown — O bundler do Vite agora é um só

O que é

Rolldown é um bundler Rust que substitui tanto o esbuild (dev) quanto o Rollup (produção) no Vite. Chegou no 1.0 RC em janeiro 2026, API estabilizada.

Por que isso importa

Quem usa Vite sabe: dev server rodava esbuild, build de produção rodava Rollup. Isso dava dor de cabeça:

  • Plugin tinha que funcionar nos dois
  • Às vezes funcionava em dev mas quebrava no build
  • Descobrir qual dos dois era o problema era chato pra caramba

Com Rolldown, um bundler só pra tudo.

Quão rápido é?

Benchmarks oficiais do time Rolldown:

React app (10.000 componentes JSX):
  Rollup 14.0s → Rolldown 3.7s (3.8x)

GitLab monorepo:
  Webpack 45.2s → Rolldown 12.1s (3.7x)

Excalidraw:
  Webpack 24.6s → Rolldown 1.5s (16.4x)

Como testar

Se usa Vite, é trivial:

npm install vite@next # Pronto. Rolldown é o bundler padrão.

Também funciona standalone:

// rolldown.config.js import { defineConfig } from 'rolldown'; export default defineConfig({ input: './src/index.ts', output: { dir: 'dist', format: 'esm', sourcemap: true }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] }, });

API de plugins compatível com Rollup, então a maioria funciona sem mudar nada:

import { defineConfig } from 'rolldown'; import react from '@vitejs/plugin-react'; export default defineConfig({ input: './src/main.tsx', plugins: [react()], output: { dir: 'dist', format: 'esm' }, });

Oxc — Parser, linter, transformer e minifier num pacote só

O projeto mais ambicioso da VoidZero. Não é uma ferramenta, é o toolchain inteiro:

  • Parser: 3x mais rápido que SWC
  • Linter (Oxlint): 50-100x mais rápido que ESLint
  • Transformer: 40x mais rápido que Babel
  • Minifier: Compressão nível Terser em velocidade nativa

O pulo do gato é que a AST é criada uma vez e reaproveitada no pipeline inteiro. Até agora cada ferramenta recriava a AST do zero. Esse desperdício acabou.

Oxlint, dá pra substituir o ESLint de verdade?

Olha os números:

Projeto TypeScript (~2.000 arquivos):
  ESLint 9: 12.4s → Oxlint: 0.13s (95x)
  Memória: ESLint ~450MB → Oxlint ~28MB (16x menos)

Não é erro de digitação. 12 segundos vs 0.13 segundos.

npm install -D oxlint npx oxlint .

Dá pra usar junto com ESLint sem tirar nada:

{ "scripts": { "lint": "oxlint . && eslint .", "lint:fast": "oxlint ." } }

Estratégia: regras comuns ficam com Oxlint, ESLint só pra plugins customizados que ainda não tem.


Rspack — Pra quando Webpack não dá pra largar

Se Rolldown é a opção pro mundo Vite, Rspack é pra quem precisa manter o webpack.config.js. Feito pelo ByteDance, pensado pra times com 5 anos de configuração acumulada.

Vamos ser realistas: tem milhões de apps em produção com Webpack. Migrar tudo pra Vite nem sempre é viável. Rspack fala: "Fica com sua config, eu faço ela rodar rápido."

Quão rápido é?

Projeto interno ByteDance:
  Webpack 5: 120s → Rspack 1.7: 36s (70% mais rápido)
  HMR: 8.2s → 1.6s (80% mais rápido)

Como testar

// rspack.config.js — quase igual ao webpack.config.js, né? const { defineConfig } = require('@rspack/cli'); module.exports = defineConfig({ entry: './src/index.tsx', output: { path: __dirname + '/dist', filename: '[name].[contenthash].js', }, module: { rules: [ { test: /\.tsx?$/, use: { loader: 'builtin:swc-loader', // SWC embutido options: { jsc: { parser: { syntax: 'typescript', tsx: true }, transform: { react: { runtime: 'automatic' } }, }, }, }, }, { test: /\.css$/, type: 'css' }, ], }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] }, optimization: { splitChunks: { chunks: 'all' } }, });

Rspack 2.0 Preview (fevereiro)

  • Cache persistente entre builds
  • Module Federation 2.0 pra micro-frontends
  • Tree shaking melhorado nível Rolldown
  • Integração Oxc pra parsing e transformação

Qual escolher?

Depende da sua situação

Seu stack atual                →    Recomendação
────────────────────────────────────────────────
Webpack + Babel + ESLint      →    Rspack + Oxlint (config quase igual)
                              →    Vite 8 + Rolldown (se puder reestruturar)
Vite + Rollup + ESLint       →    Vite 8 + Rolldown + Oxlint (só upgrade)
esbuild custom               →    Rolldown
Create React App             →    Vite 8 (CRA já era)

Comparativo

RolldownRspackesbuildWebpack
Cold build⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
HMR⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Plugins⭐⭐⭐⭐ (Rollup)⭐⭐⭐⭐⭐ (Webpack)⭐⭐⭐⭐⭐⭐⭐
Tree shaking⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Pronto pra usarRC1.7 estávelEstávelEstável

Migração passo a passo

1. Começa pelo linter (zero risco, impacto máximo)

npm install -D oxlint
{ "scripts": { "lint": "oxlint . && eslint .", "lint:ci": "oxlint ." } }

Não mexe em código, só adiciona no CI.

2. Troca o bundler

Se tá no Vite:

npm install vite@next npm run build && npm run preview # Testa em staging

Se tá no Webpack:

npm install -D @rspack/core @rspack/cli # Renomeia webpack.config.js → rspack.config.js # Troca babel-loader → builtin:swc-loader npx rspack build

3. Mede antes e depois

// build-benchmark.mjs import { performance } from 'perf_hooks'; import { execSync } from 'child_process'; const runs = 5; const times = []; for (let i = 0; i < runs; i++) { execSync('rm -rf dist .cache node_modules/.cache'); const start = performance.now(); execSync('npm run build', { stdio: 'pipe' }); times.push(performance.now() - start); } const avg = times.reduce((a, b) => a + b) / times.length; console.log(`Média: ${(avg / 1000).toFixed(2)}s`);

Cuidado com essas armadilhas

Plugins incompatíveis

Nem todo loader do Webpack tem versão Rust:

  • sass-loader → Suporte nativo do Rspack ou builtin:lightningcss-loader
  • Plugin Babel interno → Pode precisar reescrever

Output diferente

Bundlers Rust podem gerar output levemente diferente. Compara tamanhos e testa o funcionamento.

Cache do CI

Ferramenta nova = chave de cache nova:

- uses: actions/cache@v4 with: path: | node_modules/.cache .rspack-cache key: ${{ runner.os }}-build-${{ hashFiles('**/package-lock.json') }}

O que vem por aí

Agora (Q1 2026)

  • ✅ Rolldown 1.0 RC
  • ✅ Vite 8 beta com Rolldown padrão
  • 🔜 Rspack 2.0 Preview

Q2 2026

  • Rolldown 1.0 estável
  • Oxlint amplia regras pro nível ESLint core

H2 2026

  • Stack VoidZero completo integrado
  • Bundling com TypeScript nativo (sem tsc separado)

Visão final: vite build que parseia → linteia → transforma → bundlea → minifica → testa, tudo num passe só. Uma AST, um passo, zero desperdício.


Resumindo

A troca de JS pra Rust nas build tools não é modinha, é mudança estrutural:

  • Build: 4-16x mais rápido
  • Lint: 50-100x mais rápido
  • Memória: 1/10 a 1/16

O que fazer hoje:

  1. Agora: Instala Oxlint (2 minutos)
  2. Essa semana: Se usa Vite, testa vite@next
  3. Esse mês: Se usa Webpack, testa Rspack num side project
  4. Esse trimestre: Monta um roadmap de migração com o time

Webpack e Babel não vão sumir amanhã. Mas a diferença de performance é tão absurda que ficar neles custa mais em CI, deixa o ciclo de dev mais lento, e você acaba entregando menos no mesmo tempo.

O momento é agora.

RustJavaScriptViteRolldownOxcRspackBuild ToolsWeb DevelopmentPerformance

Explore ferramentas relacionadas

Experimente estas ferramentas gratuitas do Pockit