Logo de React rodeado de líneas de código con anotaciones de compilación
Volver al blog

React Compiler 1.0: el adiós a useMemo y useCallback

React Compiler 1.0 salió estable en octubre de 2025 y en mayo 2026 ya corre en producción en Meta, Vercel y más equipos serios. Memoiza componentes automáticamente y elimina useMemo, useCallback y React.memo manuales. Soporta React 17 en adelante. Guía: instalación, gotchas y cuándo no usarlo.

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ónFechaEstado
React Compiler 0.x2024Experimental
React Compiler RCmayo 2025Release candidate
React Compiler 1.07 octubre 2025Estable, production-ready
React Compiler 1.x2026Patch 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.

ReactSoporte del compiladorRuntime extra
16.xNo
17.xreact-compiler-runtime
18.xreact-compiler-runtime
19.xNo

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:

  1. 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.
  2. 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.
  3. 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:

  1. 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.
  2. 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.
  3. 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étricaAntes del compiladorDespués del compilador
Renders innecesarios en Instagram web~38% del trabajo de render~12% del trabajo de render
INP p75 en Facebook home215 ms168 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

PreguntaRespuesta 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?
No. El compilador respeta useMemo, useCallback y React.memo si ya están en tu código. Funciona tanto sobre código nuevo como sobre código legacy. La recomendación es activarlo, dejar la memoización manual existente, y limpiar archivo por archivo a medida que los modificás. En 6 meses tu base de código queda limpia sin un PR gigante de migración.
¿El compilador puede romper mi app?
En la práctica, no — está diseñado para ser conservador. Si detecta que un componente viola las Rules of React (mutación de props, side effects fuera de useEffect, etc.) simplemente lo salta y lo deja como estaba. Lo que sí puede pasar es que algunos tests que dependían de identidad referencial específica de funciones fallen, porque ahora las funciones se memoizan donde antes no. Eso es señal de tests frágiles, no de un bug del compilador.
¿Cuánta performance gana mi app con el compilador?
Depende. Meta reportó que el trabajo de render innecesario en Instagram web bajó de 38% a 12% del total, y el INP p75 de Facebook bajó de 215 ms a 168 ms. Para apps Next.js o Astro de tamaño medio, esperá entre 30 y 60 ms de mejora en INP. Si tu app ya tenía buena memoización manual exhaustiva, la diferencia va a ser menor. Si tu app no tenía casi memoización, la diferencia puede ser muy grande.
¿Necesito React 19 para usar el compilador?
No. El compilador soporta React 17, 18 y 19. Para React 17 y 18 hace falta instalar también el paquete react-compiler-runtime, que provee las primitivas que React 19 ya trae nativas. Esto es una decisión deliberada del equipo de React para que equipos legacy no tengan que esperar a migrar a 19 para beneficiarse del compilador.
¿Cómo desactivo el compilador en un componente específico?
Agregá la directiva 'use no memo' como primera línea dentro de la función del componente. El compilador lo va a saltar y dejar el componente exactamente como lo escribiste. Útil para componentes con lógica imperativa (canvas, WebGL, librerías de DOM directo) donde la memoización automática puede romper expectativas internas del código.
¿Funciona con Server Components y Next.js App Router?
Sí. El compilador detecta el contexto: si un componente es Server Component, lo deja intacto (no necesita memoización, corre en servidor). Si es Client Component (marcado con 'use client'), lo optimiza como cualquier otro. En Next.js 15+ se activa con experimental.reactCompiler = true en next.config.js.
¿Hay penalty en el tamaño del bundle al activar el compilador?
Mínimo. El compilador inyecta llamadas a primitivas internas de React que se tree-shake bien. El runtime extra para React 17/18 pesa alrededor de 1 KB gzipped. En la práctica, los renders ahorrados compensan ampliamente el overhead del código generado. Equipos que migraron reportan que el bundle total no cambió o bajó ligeramente.

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