SWC: el transformador en Rust que vive dentro del bundler
SWC no aspira a ser tu herramienta de línea de comandos, sino el motor de transpilación que otros incrustan. Escrito en Rust, desalojó a Babel dentro de Next.js y late bajo Rspack: transforma TypeScript y JSX a velocidad nativa como una pieza, no como un producto.
Si esbuild demostró que un bundler podía ser cien veces más rápido, SWC llevó la misma tesis a otro terreno: el de la pieza reutilizable. SWC —siglas de Speedy Web Compiler— es ante todo un transformador escrito en Rust, pensado no para que lo invoques tú, sino para que un bundler lo incruste. Su historia es la de un motor que se coló dentro de Next.js para desalojar a Babel y que hoy late bajo Rspack. Entender SWC es entender una estrategia distinta: no ganar la portada, sino ser el corazón de las herramientas que sí la tienen.
- Distinguir a
SWCcomo transformador incrustable, frente al todo-en-uno deesbuild. - Ver dónde vive: la migración de
BabelaSWCen Next.js y su papel enRspack. - Explicar por qué Rust es el lenguaje idóneo para una pieza que otros empotran.
- Comparar cuándo aflora
SWCfrente a cuándo afloraesbuild.
Un transformador, no un producto
La diferencia esencial entre esbuild y SWC no es el lenguaje —Go frente a Rust— sino la forma en que cada uno se ofrece al mundo. esbuild es un producto terminado: un binario que ejecutas, con su CLI, su bundler y su propio modelo de plugins. SWC es, ante todo, un componente: una biblioteca en Rust con enlaces para Node que otras herramientas empotran en su interior. Su centro de gravedad no es empaquetar, sino transformar: parsear, borrar tipos, convertir JSX, rebajar sintaxis moderna y minificar, todo a velocidad nativa.
SWC también trae un bundler propio, spack, pero nunca fue su historia principal. Lo que catapultó al proyecto no fue una CLI que la gente ejecutara, sino su adopción como motor interno de frameworks que mueven a millones de desarrolladores. SWC gana no por estar delante, sino por estar dentro.
Esa vocación de pieza se nota en cómo se distribuye. SWC es un crate de Rust con enlaces para Node, de modo que un paquete de npm puede llevar dentro un motor nativo y ofrecerlo tras una API de JavaScript familiar. No te pide cambiar de lenguaje ni de flujo: te da un componente que tu herramienta carga como cargaría cualquier otra dependencia, y que resulta ser órdenes de magnitud más veloz que su predecesor en JavaScript.
Esta distinción entre producto y componente no es pedante: cambia por completo cómo se adopta la herramienta. Un producto compite por tu atención y te pide que aprendas su CLI y su configuración; un componente compite por ser elegido por otros, y su éxito se mide en cuántas herramientas lo empotran. SWC optó por lo segundo, y por eso su cuota de mercado es enorme mientras su nombre sigue siendo desconocido para muchos de quienes lo usan a diario.
// .swcrc: configuras SWC como quien afina un motor, no una app
{
"jsc": {
"parser": { "syntax": "typescript", "tsx": true },
"target": "es2022"
}
}
// Entrada: TypeScript con JSX
const Boton = ({ texto }: { texto: string }) => <button>{texto}</button>;
Ese .swcrc no describe un proyecto entero, sino cómo debe comportarse el transformador cuando otra herramienta lo llame. Es la configuración de una pieza, no de un producto.
Dónde vive: Next.js y Rspack
La adopción que definió a SWC fue Next.js. Durante años, Next compilaba tu código con Babel; en un momento dado sustituyó todo ese motor por SWC, bautizado como el Next.js Compiler. El cambio no fue cosmético: las transformaciones pasaron a ser del orden de diecisiete veces más rápidas, la minificación dejó atrás a Terser, y el Fast Refresh y los builds se aceleraron de forma tangible. Millones de aplicaciones Next ejecutan hoy SWC de forma transitiva sin que sus autores lo nombren nunca.
Ese es, de hecho, el mayor logro de SWC: convertirse en infraestructura invisible. Cuando una herramienta se vuelve tan ubicua que la gente deja de mencionarla —como nadie menciona el compilador de C que hay bajo su lenguaje favorito—, ha ganado del todo. La migración de Babel a SWC dentro de Next fue precisamente eso: un cambio de motor que la mayoría percibió solo como ahora compila más rápido, sin enterarse de qué había debajo.
El segundo gran hogar de SWC es Rspack, el bundler compatible con la API de Webpack escrito en Rust. Rspack no reinventa la transpilación: usa SWC como su motor de transformación, expuesto a través de su loader nativo. Así, un ecosistema entero de configuraciones de Webpack corre a velocidad de Rust sin reescribirse, porque la pieza que transforma cada módulo es SWC.
Más allá de esos dos buques insignia, SWC se ha filtrado por todo el ecosistema como componente discreto:
@swc/jest, para transpilar los tests sin el peaje deBabel.@swc-nodey cargadores afines, para ejecutar TypeScript directamente en Node.- Integraciones en
Parcely en otras cadenas que buscaban un transformador nativo. - Runtimes que transpilan TypeScript antes de ejecutarlo, como Deno en sus inicios.
- Herramientas de build que cambiaron su transpilador por uno nativo sin más.
En casi todos los casos el patrón se repite: una herramienta ya existente reemplaza su transpilador en JavaScript por SWC y hereda la velocidad sin pedirte nada a cambio.
# SWC como loader dentro de Rspack: la pieza que transpila cada modulo
# rspack.config: usa builtin:swc-loader en vez de babel-loader
pnpm add -D @rspack/core
SWC transformador
Parsea, borra tipos y convierte JSX en Rust. Un motor de transpilación pensado para incrustarse, no para invocarse.
Dentro de Next.js
El Next.js Compiler reemplazó a Babel por SWC: transformaciones mucho más rápidas y minificación sin Terser.
Dentro de Rspack
El bundler compatible con Webpack usa SWC como su loader nativo. Configuración de Webpack, velocidad de Rust.
flowchart TB next[El Compiler de Next] --> swc[SWC en Rust] rspack[Rspack: builtin swc loader] --> swc jest[swc jest en los tests] --> swc swc --> job[Transpila TS y JSX a velocidad nativa] style swc fill:#a6e3a1,color:#11111b style job fill:#89b4fa,color:#11111b
Por qué Rust para una pieza incrustada
La elección de Rust cobra todo su sentido precisamente porque SWC está pensado para vivir dentro de otro programa. Un transformador incrustado corre en procesos largos —un dev server que no se apaga en horas, un bundler que atiende miles de módulos— donde las pausas de recolección de basura y el consumo de memoria de un motor en JavaScript se acumularían. Rust ofrece velocidad nativa sin recolector de basura, seguridad de memoria comprobada en compilación y concurrencia sin condiciones de carrera, justo las propiedades que quieres en un componente que otros empotran y del que dependen. En concreto, para un motor incrustado eso se traduce en:
- Sin recolector de basura: nada de pausas que congelen el proceso anfitrión.
- Seguridad de memoria en compilación: sin fugas ni corrupción que herede quien lo empotra.
- Concurrencia sin carreras: puede paralelizar el trabajo sin arriesgar la estabilidad.
A eso se suma la ergonomía de distribución: Rust compila a bibliotecas nativas que se exponen a Node mediante enlaces, de modo que un paquete de npm puede llevar dentro un motor en Rust y usarse desde JavaScript como si fuera una dependencia más. SWC no te pide cambiar de lenguaje; te da un motor nativo detrás de una interfaz familiar.
Hay un matiz que distingue este caso del de un producto autónomo. Un binario que ejecutas y termina puede permitirse cierta laxitud con la memoria; un motor incrustado en un dev server que vive horas, o en un bundler que procesa decenas de miles de módulos por sesión, no. Ahí la ausencia de recolector de basura y la seguridad de memoria comprobada de Rust dejan de ser lujos y pasan a ser requisitos: garantizan que el componente no degrade al proceso anfitrión con pausas ni con fugas. Rust no es solo rápido; es predecible, y eso es justo lo que un motor empotrado necesita.
Merece la pena notar que esbuild eligió Go y SWC eligió Rust para el mismo objetivo, y que ambos funcionan. No hay un único lenguaje correcto para escribir tooling veloz; hay una única condición, salir de JavaScript hacia algo compilado y paralelo. Go dio a esbuild una concurrencia sencilla y tiempos de compilación cómodos; Rust dio a SWC y a Oxc un control de memoria sin recolector que encaja mejor con la vida de un componente incrustado. Dos apuestas, un mismo diagnóstico.
esbuild frente a SWC
Ambos nacieron con el mismo enemigo —el peaje de Babel— y en la misma época, pero eligieron formas opuestas de librar la batalla. esbuild se presenta como un producto autónomo que además empaqueta; SWC se presenta como un motor de transpilación que otros incrustan. Rara vez eliges SWC de forma directa: eliges Next.js o Rspack y lo heredas. En cambio eliges esbuild como herramienta cuando quieres empaquetar algo tú mismo sin arrastrar un bundler pesado.
La comparación, punto por punto, aclara que no son rivales sino respuestas de forma distinta al mismo problema:
- Superficie:
esbuildes una CLI y un producto;SWCes una biblioteca que se incrusta. - Alcance:
esbuildtranspila y empaqueta;SWCconcentra su fuerza en transpilar. - Cómo llega a ti:
esbuildlo invocas;SWClo trae tu framework por debajo. - Lenguaje: Go frente a Rust, dos caminos hacia la misma velocidad nativa.
# Dos formas de matar el peaje de Babel
esbuild -> Go, producto y bundler, lo invocas tu
SWC -> Rust, motor incrustado, lo incrusta tu framework
Que existan dos respuestas distintas al mismo problema no es un fallo del ecosistema, sino una señal de salud: esbuild sirve mejor a quien quiere una herramienta autónoma, y SWC a quien construye un framework y necesita un motor que empotrar. La lección final de este nivel será, precisamente, que casi nunca eliges tú entre ambos, sino que lo hace la herramienta de más arriba que decides usar. Y esa es una buena noticia: no tienes que convertirte en experto de motores para decidir bien, solo en frameworks.
Dicho en una regla práctica:
- Si escribes un script o empaquetas una librería tú mismo, aflora
esbuild. - Si abres un proyecto Next.js o
Rspack, ya estáSWCtrabajando por debajo. - Si te preguntas cuál instalo, casi siempre la respuesta es ninguno, lo trae tu framework.
Esa es, en el fondo, la firma de una infraestructura madura: la que resuelve tu problema sin pedirte siquiera que la conozcas, y que solo asoma cuando decides mirar debajo del capó.
Aunque su fama venga de Next.js, SWC sostiene toda una constelación de herramientas: @swc/jest para transpilar en los tests, @swc-node para ejecutar TypeScript en Node, e integraciones en Parcel y otros bundlers. Cuando veas que tu suite de tests o tu dev server han acelerado sin que tocaras nada, hay una probabilidad alta de que SWC esté trabajando por debajo, invisible y rápido.
SWC enseña una lección estratégica que trasciende la transpilación. En la generación anterior, cada capa del tooling era un producto con su propio nombre en la portada: Babel transpilaba, Webpack empaquetaba, Terser minificaba, y el ecosistema pagaba el peaje de la interpretación una y otra vez, capa sobre capa. SWC invirtió la jugada. En lugar de competir por ser la app que el desarrollador ejecuta, se propuso ser el motor que las apps incrustan, y desde esa posición desalojó a Babel del interior de Next.js sin pedirle a nadie que cambiara su forma de trabajar. Fíjate en la elegancia de la maniobra: millones de proyectos migraron de Babel a un motor en Rust sin escribir una línea, porque la migración ocurrió una capa por debajo de donde ellos viven. Esta es la forma madura de sustituir infraestructura: no convencer a cada usuario de que adopte tu herramienta, sino convertirte en la pieza que su herramienta ya usa. Y anticipa lo que viene. SWC probó que un motor en Rust podía colonizar el ecosistema desde dentro, transformador a transformador; Oxc, que verás a continuación, generaliza esa idea a toda la cadena bajo un solo AST. La partida no la ganan las herramientas más vistosas, sino las que se vuelven fronteras estables sobre las que otros construyen. Aprende a distinguir el producto del motor: el primero es el andamio de una temporada, el segundo es el cimiento de una década.
- Crea o abre un proyecto Next.js y localiza en su configuración las opciones del Compiler: son directivas que Next traduce a transformaciones de
SWC. - Escribe un
.swcrcmínimo conparserde TypeScript ytsxactivado, y transpila un componente suelto con@swc/cli. - Compara la salida de
SWCcon la deBabelsobre el mismo archivo: mismo objetivo, motores distintos. - Investiga si algún proyecto tuyo usa
@swc/jestoRspacky confirma queSWCcorre por debajo sin que lo hubieras nombrado. - Explica en dos frases por qué
SWCoptó por ser un motor incrustable en Rust en vez de un producto autónomo comoesbuild.