Back

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:

  1. Babel parsea el código a AST → transforma → serializa
  2. ESLint parsea el mismo código en otro AST → verifica reglas
  3. Webpack/Rollup lo parsea otra vez → resuelve módulos → bundlea
  4. 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

ProblemaJavaScriptRust
VelocidadJIT, overhead de V8Binario nativo, zero-cost abstractions
MemoriaGC con pausas impredeciblesOwnership model, sin GC
ParalelismoWorker threads con costo de serializaciónMulti-threading nativo
ParseoCada herramienta crea su propio ASTUn 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

RolldownRspackesbuildWebpack
Cold build⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
HMR⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Plugins⭐⭐⭐⭐ (Rollup)⭐⭐⭐⭐⭐ (Webpack)⭐⭐⭐⭐⭐⭐⭐
Tree shaking⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Listo hoyRC1.7 estableEstableEstable

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 o builtin: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 tsc aparte)

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:

  1. Ahora: Instala Oxlint (2 minutos)
  2. Esta semana: Si usas Vite, prueba vite@next
  3. Este mes: Si usas Webpack, prueba Rspack en un proyecto secundario
  4. 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.

RustJavaScriptViteRolldownOxcRspackBuild ToolsWeb DevelopmentPerformance

Explora herramientas relacionadas

Prueba estas herramientas gratuitas de Pockit