Si todavía estás escribiendo useMemo y useCallback a mano en mayo de 2026, estás trabajando de más. React Compiler 1.0 salió estable el 7 de octubre de 2025, lleva seis meses corriendo en producción en Meta sobre el código que mueve Facebook y Instagram, y para este momento varios equipos serios (Vercel, Shopify, Netflix) lo activaron por default en sus pipelines. El compilador detecta qué componentes y valores se pueden memoizar, lo hace solo en tiempo de build, y deja tu código fuente limpio de la decoración defensiva que arrastrábamos desde React 16.
Esto no es un upgrade cosmético: cambia cómo se escribe React y, más importante, qué dejás de escribir. Las reglas de “envolvé esto en useMemo si está caro” se invierten — el compilador asume que todo es memoizable y vos solo indicás las pocas excepciones. Para un dev que recién migra desde un setup pre-compiler, el primer choque es ver cuánto código sobra. Este post repasa qué hace exactamente el compilador, cómo instalarlo en un proyecto existente, qué se rompe en la práctica y cuándo no usarlo.
Qué hace el React Compiler
El compilador analiza tu código de React en tiempo de build (es un plugin de Babel) y reescribe los componentes para que memoicen automáticamente sus renders y los valores intermedios que dependen de props o state. Lo que antes hacías a mano:
function PostCard({ post, onLike }) {
const formattedDate = useMemo(
() => formatDate(post.publishedAt),
[post.publishedAt]
)
const handleClick = useCallback(
() => onLike(post.id),
[onLike, post.id]
)
return (
<article onClick={handleClick}>
<h2>{post.title}</h2>
<time>{formattedDate}</time>
</article>
)
}
export default React.memo(PostCard)
Pasa a verse así:
function PostCard({ post, onLike }) {
const formattedDate = formatDate(post.publishedAt)
const handleClick = () => onLike(post.id)
return (
<article onClick={handleClick}>
<h2>{post.title}</h2>
<time>{formattedDate}</time>
</article>
)
}
export default PostCard
El compilador identifica que formattedDate depende de post.publishedAt, que handleClick depende de onLike y post.id, y emite código equivalente al memoizado sin que tengas que escribirlo. El resultado en runtime es indistinguible del primer ejemplo — misma performance, sin el ruido visual.
Lo que no hace
El compilador no es magia: no optimiza algoritmos lentos, no convierte un O(n²) en O(n), no descubre que tu fetch innecesario se puede cachear. Lo que hace, y solo eso, es eliminar re-renders y re-cálculos innecesarios introducidos por el modelo de identidad referencial de JavaScript. Si tu componente es lento porque corre un JSON.parse de 5MB en cada render, el compilador no te salva — te avisa que el render se memoizó, pero el cuerpo del componente sigue siendo lento.
Estado del compilador en mayo de 2026
| Versión | Fecha | Estado |
|---|---|---|
| React Compiler 0.x | 2024 | Experimental |
| React Compiler RC | mayo 2025 | Release candidate |
| React Compiler 1.0 | 7 octubre 2025 | Estable, production-ready |
| React Compiler 1.x | 2026 | Patch releases incrementales |
Para mayo de 2026 el compilador lleva siete meses en producción, los bugs grandes se cerraron y la comunidad publicó suficientes post-mortems como para que las trampas estén documentadas (Meta engineering, React blog). Para un proyecto nuevo, activarlo es la decisión por defecto. Para un proyecto legacy con mucho código en violaciones de las Rules of React, hay trabajo previo.
Compatibilidad de versiones de React
Esto sorprende a la mayoría: el compilador no requiere React 19. Soporta React 17 en adelante a través de un paquete runtime opcional. Para React 19+ funciona sin runtime extra.
| React | Soporte del compilador | Runtime extra |
|---|---|---|
| 16.x | No | — |
| 17.x | Sí | react-compiler-runtime |
| 18.x | Sí | react-compiler-runtime |
| 19.x | Sí | No |
Es una decisión deliberada del equipo de React: el compilador es valioso para legacy también, y obligar a actualizar a React 19 hubiera dejado afuera a la mayoría de equipos enterprise.
Cómo instalarlo
Tres pasos. En un proyecto con Babel ya configurado (Next.js, Astro con React, CRA legacy, Vite con @vitejs/plugin-react):
1. Instalá los paquetes
npm install --save-dev babel-plugin-react-compiler@latest
npm install --save-dev eslint-plugin-react-compiler@latest
Si estás en React 17 o 18, agregá también:
npm install react-compiler-runtime@latest
2. Activá el plugin de Babel
En babel.config.js:
module.exports = {
plugins: [
['babel-plugin-react-compiler', {
target: '19', // o '18', '17'
}],
],
}
En Next.js 15+ se activa en next.config.js:
module.exports = {
experimental: {
reactCompiler: true,
},
}
En Vite con @vitejs/plugin-react:
import react from '@vitejs/plugin-react'
export default {
plugins: [
react({
babel: {
plugins: ['babel-plugin-react-compiler'],
},
}),
],
}
3. Activá el ESLint rule
En .eslintrc.cjs:
module.exports = {
plugins: ['react-compiler'],
rules: {
'react-compiler/react-compiler': 'error',
},
}
El ESLint rule es crítico: marca componentes que violan las Rules of React y que por lo tanto el compilador va a saltar (no romper, saltar — los compila como antes, sin optimización). Sin este rule no te enterás de qué quedó afuera.
Qué hacer con tu useMemo y useCallback existentes
Tres opciones, en orden de pragmatismo creciente:
- Dejarlos. El compilador los respeta. Tu código sigue funcionando exacto. Esto es lo razonable durante la primera semana mientras validás que nada se rompe.
- Quitarlos archivo por archivo a medida que tocás cada uno. Cuando entrás a un componente para modificarlo, le quitás la decoración manual. En 6 meses la base de código está limpia.
- Codemod masivo. Hay un codemod oficial (
react-compiler-codemod) que elimina memoización manual en bulk. Riesgo: si tu codebase tiene patrones raros, el codemod puede tocar lo que no debía.
La opción 2 es la que recomendamos a los clientes. Los codemods masivos en code base productivo son una receta para PRs gigantes que nadie revisa bien.
Cuándo NO usar el compilador
Hay tres escenarios donde activarlo trae más dolor que beneficio:
- Codebase con muchas violaciones de Rules of React. Si tu equipo escribió componentes que mutan props, escriben directo a refs sin
useRef, o tienen efectos sin deps array, el compilador va a saltar esos componentes (no romper, pero no optimizar tampoco). El ESLint rule te dice cuántos. Si son la mayoría, el compilador no compra nada hasta que se limpie el código. - App muy chica. Para un dashboard de 20 componentes que renderiza una vez al día, la diferencia es invisible. No introduce daño, pero tampoco aporta valor.
- Setup de build muy custom. Equipos que tienen pipelines de SWC heavily customizados, o usan Webpack 4 con loaders no estándar, pueden encontrar fricción para integrar el plugin. Es resoluble, pero requiere tiempo.
El escape hatch: 'use no memo'
A nivel componente, podés decirle al compilador “este no lo toques”:
function ComponenteRaro() {
'use no memo'
// El compilador deja este componente como está,
// sin memoización automática.
}
Útil para componentes con lógica imperativa (canvas, WebGL, librerías de DOM directo) donde la memoización rompe expectativas internas.
El impacto medible
Meta publicó números de su rollout en el post de anuncio del 1.0:
| Métrica | Antes del compilador | Después del compilador |
|---|---|---|
| Renders innecesarios en Instagram web | ~38% del trabajo de render | ~12% del trabajo de render |
| INP p75 en Facebook home | 215 ms | 168 ms |
| Líneas de useMemo/useCallback en codebase | ~38.000 | ~2.100 |
Las cifras son de Meta sobre Meta, con todas las cautelas de “tu codebase no es Facebook”. Pero la tendencia es clara: la mayor parte del trabajo de optimización manual era removible. El compilador no inventó performance, dejó visible lo que el modelo manual estaba ocultando.
Para un proyecto Next.js o Astro con React de tamaño medio, esperar entre 30 y 60 ms de mejora en INP después de activarlo es razonable según reportes de la comunidad. No es una bala de plata, pero es un upgrade gratis sobre código que ya tenés.
Cómo encaja con Server Components
Pregunta frecuente: ¿el compilador optimiza Server Components? Respuesta corta: no hace falta. Server Components ya corren en el servidor y no tienen el ciclo de render que justifica memoización en cliente. El compilador detecta el contexto y deja los Server Components intactos. Para Client Components (los marcados con 'use client') el compilador trabaja igual que con cualquier componente.
Si tu app vive en Next.js App Router o Astro con islas de React, la mayoría del beneficio del compilador se ve en los Client Components — exactamente los que más se benefician de evitar re-renders innecesarios. Para más sobre cómo encaja esto con el modelo de Server Components, ver la docu oficial de React.
Tabla resumen
| Pregunta | Respuesta corta |
|---|---|
| ¿Es estable? | Sí, 1.0 desde 7 octubre 2025 |
| ¿Reemplaza useMemo y useCallback? | Sí, automáticamente |
| ¿Necesito React 19? | No, soporta 17+ con runtime extra |
| ¿Está activo por default? | No, hay que instalar y configurar |
| ¿Rompe código existente? | No: salta componentes que violan Rules of React |
| ¿Cómo desactivarlo en un componente? | Directiva 'use no memo' al inicio |
Preguntas frecuentes
¿Tengo que reescribir mis componentes para usar el compilador?
¿El compilador puede romper mi app?
¿Cuánta performance gana mi app con el compilador?
¿Necesito React 19 para usar el compilador?
¿Cómo desactivo el compilador en un componente específico?
¿Funciona con Server Components y Next.js App Router?
¿Hay penalty en el tamaño del bundle al activar el compilador?
Azirgo
¿Listo para construir tu Producto Digital?
Sitios web, apps móviles, software a medida y soluciones blockchain. Cuéntanos qué tienes en mente y armamos un plan claro contigo.
- Cotización clara en 48 horas
- Equipo en Ecuador, atención en español
- Desde un MVP hasta un producto en producción