Del bundler al linter, todo se está reescribiendo en Rust
Si has estado atento a las noticias del ecosistema frontend últimamente, habrás notado un patrón: el bundler, el linter, el transpilador, el minificador... uno tras otro, todos se están reescribiendo en Rust.
Y no estamos hablando de un 20% más rápido. Estamos hablando de 10x a 100x.
Rolldown alcanzó su 1.0 RC y es el bundler por defecto en Vite 8 beta. Oxlint ya le saca 50-100x a ESLint. Rspack 2.0 Preview sale este mes.
Si todavía estás con Webpack, es momento de prestar atención.
¿Por qué Rust?
Las herramientas JS tienen un problema estructural
Piénsalo un momento. JavaScript fue diseñado para el navegador. Usarlo para compilar miles de archivos en un solo hilo, con garbage collector de por medio... es un cuello de botella inevitable.
Cuando lanzas npm run build, internamente pasa esto:
- Babel parsea el código a AST → transforma → serializa
- ESLint parsea el mismo código en otro AST → verifica reglas
- Webpack/Rollup lo parsea otra vez → resuelve módulos → bundlea
- Terser parsea el resultado → comprime
El mismo código se parsea 4+ veces, con 4 formatos de AST diferentes, todo single-threaded, con pausas del GC. No tiene sentido.
Lo que Rust cambia
| Problema | JavaScript | Rust |
|---|---|---|
| Velocidad | JIT, overhead de V8 | Binario nativo, zero-cost abstractions |
| Memoria | GC con pausas impredecibles | Ownership model, sin GC |
| Paralelismo | Worker threads con costo de serialización | Multi-threading nativo |
| Parseo | Cada herramienta crea su propio AST | Un solo AST compartido |
Resultado: builds de 30s bajan a 2s. Linting de 10s a 0.1s. Cifras reales, no sintéticas.
Quién está haciendo qué
┌─────────────────────────────────────────────────────────────┐
│ VoidZero (Evan You) │
│ Toolchain JS unificado en Rust │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │
│ │ Vite │ │ Rolldown │ │ Oxc │ │ Vitest │ │
│ │ Dev Svr │ │ Bundler │ │ Parser │ │ Test Runner │ │
│ │ │ │ │ │ Linter │ │ │ │
│ │ │ │ │ │ Minifier │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌──────────────────────┐ ┌──────────────────────┐
│ Rspack (ByteDance) │ │ Biome (Comunidad) │
│ Compatible Webpack │ │ Formatter + Linter │
└──────────────────────┘ └──────────────────────┘
El centro de todo esto es VoidZero, la empresa de Evan You (creador de Vue.js y Vite). La idea es simple: "¿Por qué cada herramienta parsea el código por separado? Con una vez basta."
Rolldown — El bundler de Vite se unifica por fin
Qué es
Rolldown es un bundler Rust que reemplaza tanto esbuild (dev) como Rollup (producción) en Vite. Llegó a 1.0 RC en enero 2026, API estabilizada.
Por qué es relevante
Los que usan Vite lo saben: el servidor de desarrollo usaba esbuild, y el build de producción usaba Rollup. Eso daba problemas:
- Los plugins tenían que funcionar en ambos
- A veces algo iba bien en dev pero rompía en producción
- Depurar cuál de los dos fallaba era tedioso
Con Rolldown, un solo bundler para todo.
¿Qué tan rápido?
Benchmarks oficiales de 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)
Cómo probarlo
Si usas Vite, es trivial:
npm install vite@next # Listo. Rolldown es el bundler por defecto.
También 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'] }, });
La API de plugins es compatible con Rollup, así que la mayoría funciona sin cambios:
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 y minifier, todo en uno
El proyecto más ambicioso de VoidZero. No es una herramienta sola, es un toolchain completo:
- Parser: 3x más rápido que SWC
- Linter (Oxlint): 50-100x más rápido que ESLint
- Transformer: 40x más rápido que Babel
- Minifier: Compresión nivel Terser a velocidad nativa
El truco está en que el AST se crea una sola vez y se reutiliza en todo el pipeline. Hasta ahora, cada herramienta recreaba el AST desde cero. Eso se acabó.
Oxlint, ¿de verdad reemplaza a ESLint?
Mira los números:
Proyecto TypeScript (~2,000 archivos):
ESLint 9: 12.4s → Oxlint: 0.13s (95x)
Memoria: ESLint ~450MB → Oxlint ~28MB (16x menos)
No es una errata. 12 segundos vs 0.13 segundos.
npm install -D oxlint npx oxlint .
Puedes usarlo junto con ESLint sin quitar nada:
{ "scripts": { "lint": "oxlint . && eslint .", "lint:fast": "oxlint ." } }
Estrategia recomendada: las reglas comunes las maneja Oxlint, y ESLint solo queda para los plugins custom que aún no tiene.
Rspack — Para cuando no puedes dejar Webpack
Si Rolldown es la opción para el mundo Vite, Rspack es para proyectos que necesitan mantener su webpack.config.js. Hecho por ByteDance, pensado para equipos con 5 años de configuración acumulada.
Seamos realistas: hay millones de apps en producción con Webpack. Migrar todo a Vite no siempre es viable. Rspack dice: "Quédate con tu configuración, yo la hago rápida."
¿Qué tan rápido?
Proyecto interno ByteDance:
Webpack 5: 120s → Rspack 1.7: 36s (70% más rápido)
HMR: 8.2s → 1.6s (80% más rápido)
Cómo probarlo
// rspack.config.js — casi idéntico a webpack.config.js 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 incorporado 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 (febrero)
- Caché persistente entre builds
- Module Federation 2.0 para micro-frontends
- Tree shaking mejorado a nivel Rolldown
- Integración Oxc para parseo y transformación
¿Cuál elijo?
Según tu situación
Tu stack actual → Recomendación
────────────────────────────────────────────────
Webpack + Babel + ESLint → Rspack + Oxlint (config casi igual)
→ Vite 8 + Rolldown (si puedes restructurar)
Vite + Rollup + ESLint → Vite 8 + Rolldown + Oxlint (solo upgrade)
esbuild custom → Rolldown
Create React App → Vite 8 (CRA ya fue)
Comparativa
| Rolldown | Rspack | esbuild | Webpack | |
|---|---|---|---|---|
| Cold build | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ |
| HMR | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| Plugins | ⭐⭐⭐⭐ (Rollup) | ⭐⭐⭐⭐⭐ (Webpack) | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| Tree shaking | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| Listo hoy | RC | 1.7 estable | Estable | Estable |
Migración paso a paso
1. Empieza por el linter (sin riesgo, máximo impacto)
npm install -D oxlint
{ "scripts": { "lint": "oxlint . && eslint .", "lint:ci": "oxlint ." } }
No tocas código existente, solo agregas al CI.
2. Cambia el bundler
Si usas Vite:
npm install vite@next npm run build && npm run preview # Verifica en staging
Si usas Webpack:
npm install -D @rspack/core @rspack/cli # Renombra webpack.config.js → rspack.config.js # Cambia babel-loader → builtin:swc-loader npx rspack build
3. Mide antes y después
// 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(`Promedio: ${(avg / 1000).toFixed(2)}s`);
Cuidado con estas trampas
Plugins incompatibles
No todos los loaders de Webpack tienen versión Rust:
sass-loader→ Soporte nativo de Rspack obuiltin:lightningcss-loader- Plugins Babel internos → Puede que haya que reescribirlos
Output diferente
Los bundlers Rust pueden generar output ligeramente distinto. Compara tamaños y verifica el funcionamiento.
Caché del CI
Herramienta nueva = clave de caché nueva:
- uses: actions/cache@v4 with: path: | node_modules/.cache .rspack-cache key: ${{ runner.os }}-build-${{ hashFiles('**/package-lock.json') }}
Lo que viene
Ahora (Q1 2026)
- ✅ Rolldown 1.0 RC
- ✅ Vite 8 beta con Rolldown por defecto
- 🔜 Rspack 2.0 Preview
Q2 2026
- Rolldown 1.0 estable
- Oxlint amplía reglas al nivel de ESLint core
H2 2026
- VoidZero stack completo integrado
- Bundling con TypeScript nativo (sin
tscaparte)
La visión final: vite build que parsea → lintea → transforma → bundlea → minifica → testea, todo en un solo pase. Un AST, un paso, cero redundancia.
En resumen
El paso de JS a Rust en las herramientas de build no es una moda, es un cambio estructural:
- Build: 4-16x más rápido
- Lint: 50-100x más rápido
- Memoria: 1/10 a 1/16
Qué hacer hoy:
- Ahora: Instala Oxlint (2 minutos)
- Esta semana: Si usas Vite, prueba
vite@next - Este mes: Si usas Webpack, prueba Rspack en un proyecto secundario
- Este trimestre: Arma un roadmap de migración con tu equipo
Webpack y Babel no van a desaparecer mañana. Pero la diferencia de rendimiento es tan brutal que quedarse cuesta más en CI, ralentiza tu ciclo de desarrollo, y te deja construir menos en el mismo tiempo.
El momento es ahora.
Explora herramientas relacionadas
Prueba estas herramientas gratuitas de Pockit