← volver Una terminal ámbar brillante en el escritorio de un desarrollador por la noche, una taza de café vacía junto a un teclado gastado, ventana mojada por lluvia de fondo

Actualizar a Next.js 16: Mis Notas Reales de Migración

Hace tres semanas estaba sentado en la oficina de Seahawk un jueves por la tarde, bastante seguro de que la actualización de Next.js 15 a 16 en uno de mis sitios de portafolio personal tomaría cuarenta minutos máximo. Tomó el resto del día. ¿Y honestamente? El changelog no te prepara del todo para las partes que realmente se rompen.

He construido y entregado más de 12,000 sitios en este punto. No lo digo para alardear, lo digo porque he hecho suficientes migraciones de estas para saber cuándo la guía oficial de actualización está pasando por alto algo. Next.js 16 pasa por alto algunas cosas. Así que aquí están mis notas reales, escritas de la forma en que hubiera deseado que alguien las escribiera para mí.

---

Por Qué Me Molestó en Actualizar

Turbopack. Esa es la respuesta corta.

La respuesta más larga es que dos de mis sitios estaban en Next.js 14, uno ya estaba en 15, y había estado viendo cómo se desarrollaba la historia de Turbopack durante aproximadamente dieciocho meses. La versión 16 es el primer lanzamiento donde Turbopack está activado por defecto para next dev. No es un detalle menor. En una construcción de comercio electrónico de tamaño medio que hice para un cliente de moda el año pasado, los tiempos de arranque en frío en desarrollo eran brutales, hablamos de 12 a 18 segundos en la primera carga. Si Turbopack genuinamente lo reduce, vale la pena el dolor de migración.

Spoiler: sí lo reduce. En el mismo tipo de proyecto, estoy viendo 3 a 4 segundos en frío. Eso es real.

Pero el camino para llegar allá tiene algunos bordes afilados.

---

El Comando de Actualización Real (y Qué Ejecutar Primero)

Antes de tocar nada, ejecuta una auditoría completa de tu configuración actual. Uso npx @next/codemod@latest religiosamente ahora. No atrapará todo pero sí atrapa los cambios de nombre obvios y las llamadas API deprecadas. Ejecútalo, confirma la salida, luego aumenta tu package.json.

La actualización en sí:

  1. Actualiza next, react y react-dom a sus versiones objetivo en package.json
  2. Ejecuta npm install (o pnpm install si eres sensato, he estado con pnpm durante dos años)
  3. Ejecuta el codemod: npx @next/codemod@latest upgrade
  4. Inicia next dev y lee cada advertencia antes de tocar un solo componente
  5. Arregla los problemas de configuración antes de arreglar los problemas de componentes, el orden importa aquí

El paso del codemod es donde he visto que la gente se tropieza. Lo saltan, se encuentran con tres errores separados, y pasan una hora buscando cosas que se habrían arreglado automáticamente. No lo saltes.

---

Cambios en next.config.js Que Te Morderán

Esta fue la primera sorpresa real para mí. La API de configuración cambió más de lo que esperaba.

El bloque `experimental` es más delgado ahora

Varios flags que vivieron en experimental durante el año o dos pasados han sido promovidos a estable (y movidos al nivel superior) o removidos completamente. Los dos con los que me topé personalmente:

  • experimental.appDir, desapareció. App Router es ahora el predeterminado. Si lo tienes en tu configuración, mostrará una advertencia (y en algunas configuraciones, un error directo).
  • experimental.serverComponentsExternalPackages, promovido a serverExternalPackages en el nivel superior de tu configuración.

El segundo me atrapó en un sitio que usa Prisma. La compilación fallaba silenciosamente en el bundle del servidor y pasé probablemente cuarenta minutos mirando el archivo equivocado antes de verlo. Revisa tu next.config.js de arriba a abajo antes de asumir que el problema es un componente.

La configuración de Turbopack está en un lugar nuevo

Si tenías alguna configuración personalizada de Webpack y estás cambiando a Turbopack (que lo harás, ya que ahora es el predeterminado para dev), necesitas saber que tu función webpack() en next.config.js no se aplica cuando Turbopack está corriendo. Solo se aplica durante next build, que todavía usa Webpack.

Esto importa si tenías manejo personalizado de SVG (yo uso SVGR en la mayoría de los proyectos), alias de módulos personalizados, o cualquier configuración de loader. Tendrás que replicar esos en el nuevo bloque de configuración de turbopack. La documentación de configuración de Turbopack en Next.js es bastante decente en esto, vale la pena leerla antes de asumir que algo está roto.

---

Compatibilidad con React 19: La Trampa Silenciosa

Next.js 16 viene con React 19 como su dependencia par. Si estás actualizando desde Next.js 14 (saltándote 15), estás saltando dos versiones principales de React de una sola vez. Es ahí donde las cosas se ponen intensas.

El problema más grande que tuve fue con librerías de componentes de terceros más antiguas. Tenía un sitio de cliente que usaba una librería de tablas que internamente usaba ReactDOM.render(). React 19 eliminó esa API completamente, fue deprecada en React 18 pero aún funcionaba. En 19, lanza un error. Definitivamente.

Me pasé una mañana de martes con esto. El mensaje de error no te apunta inmediatamente a la librería; solo te dice que ReactDOM.render ya no es compatible. Ejecuta npm ls react para ver qué paquetes en tu árbol tienen declaraciones conflictivas de dependencia par de React. Ese comando solo me ahorró probablemente dos horas de adivinanzas.

Unos pocos patrones que vale la pena conocer específicamente para React 19:

  • forwardRef ya no es requerido para pasar refs; los refs ahora son una prop regular. Los componentes antiguos que usan forwardRef siguen funcionando, pero verás advertencias de deprecación.
  • use() es estable ahora y genuinamente útil para datos asincronos en componentes cliente. He comenzado a usarlo en preferencia a useEffect + state para búsquedas directas.
  • Las Server Actions tienen requisitos de tipo más estrictos. Si tenías algo débilmente tipado en tus firmas de acción, TypeScript ahora lo encontrará.

---

App Router: Qué Cambió en el Comportamiento de Caché

Este es sutil y te atrapará en producción si no prestas atención.

En Next.js 14, fetch() dentro de Server Components estaba en caché agresivamente de manera predeterminada. Tenías que optar por no hacerlo con { cache: 'no-store' }. En Next.js 15 invirtieron esto (fetch no está en caché de manera predeterminada), y Next.js 16 continúa en esa dirección con algunos controles más explícitos.

Si migraste de 14 a 16 en un solo salto (como lo hice con uno de mis sitios), tus páginas que se basaban en el viejo comportamiento de caché predeterminado comenzarán a hacer búsquedas en vivo en cada solicitud. Para algunas páginas, está bien. Para otras, bombardeará tu API y hundirá tus tiempos de respuesta.

The fix is explicit: use export const revalidate = 3600 (or whatever interval makes sense) at the route segment level, or pass { next: { revalidate: 3600 } } directly in your fetch call. The Next.js caching documentation has a solid breakdown of what caches what and when.

Audité cada ruta de búsqueda de datos en el sitio afectado usando un grep rápido para fetch( y agregué declaraciones de caché explícitas. Tomó alrededor de dos horas pero valió la pena, los tiempos de respuesta bajaron de ~800ms promedio a ~120ms después de la corrección.

---

Turbopack en la Práctica: Lo Bueno y lo Molesto

Déjame ser directo contigo: Turbopack es impresionante. Los tiempos de inicio en frío son dramáticamente mejores. El reemplazo de módulos en caliente se siente casi instantáneo en la mayoría de los cambios. Para el desarrollo día a día es una mejora significativa de calidad de vida.

Pero hay áreas ásperas.

Lo que no funciona todavía

En el momento en que hice estas migraciones, un puñado de cosas aún no eran totalmente compatibles con Turbopack para dev:

  • Algunos loaders específicos de Webpack todavía no tienen equivalente en Turbopack. SVGR necesitaba un cambio de configuración (la sintaxis de reglas de Turbopack es diferente de module.rules de Webpack).
  • Transformaciones personalizadas de Babel. Turbopack usa solo SWC. Si tu proyecto tiene un .babelrc o babel.config.js con plugins personalizados, no se ejecutarán. Esta es una limitación conocida y el equipo de Vercel es transparente al respecto en su documentación de Turbopack.
  • Algunas combinaciones de plugins PostCSS se comportan de manera inesperada en desarrollo. Lo vi en Tailwind v4 + configuración PostCSS personalizada, la solución fue fijar explícitamente el orden del plugin PostCSS.

La bandera `--turbopack` ahora es innecesaria

Dado que Turbopack es el predeterminado para next dev en la versión 16, ya no necesitas la bandera --turbopack. Si la tienes en tus scripts de package.json por experimentar en la versión 15, no causará problemas, pero es redundante. Limpia tus scripts.

---

Actualizaciones de configuración de TypeScript y ESLint

Dos cosas de mantenimiento que me confundieron.

Next.js 16 requiere TypeScript 5.x. Si todavía estás en TypeScript 4.x (algunos proyectos antiguos lo están), necesitas actualizar eso por separado. Ejecuta npx tsc --version antes de empezar cualquier otra cosa.

La historia de la configuración de ESLint también cambió. Next.js 16 incluye soporte para ESLint 9, y ESLint 9 usa formato de configuración plana (eslint.config.js) en lugar del antiguo formato .eslintrc. Si todavía estás en el formato antiguo, Next.js caerá de manera elegante, pero verás una advertencia. Migré dos de mis proyectos a la configuración plana mientras estaba en eso de todos modos. Honestamente, es más limpio una vez que superas la fricción inicial.

---

Mi lista de verificación de migración (en orden)

Esto es lo que le daría a cualquiera en mi equipo que haga esta actualización:

  1. Haz una copia de seguridad de tus archivos de configuración actuales y del archivo de bloqueo antes de tocar nada
  2. Verifica tu versión de Node.js, Next.js 16 requiere Node 18.18 o posterior
  3. Ejecuta npx @next/codemod@latest upgrade en la versión actual primero
  4. Actualiza las versiones de next, react, react-dom en package.json e instala
  5. Revisa next.config.js en busca de banderas experimental promovidas o eliminadas
  6. Ejecuta npm ls react para identificar conflictos de bibliotecas de terceros
  7. Busca en tu código fetch( y audita las declaraciones de almacenamiento en caché
  8. Busca cualquier .babelrc o cargadores específicos de Webpack que necesiten equivalentes de Turbopack
  9. Inicia dev, lee todas las advertencias antes de tocar componentes
  10. Ejecuta una compilación de producción local (next build) antes de desplegar en cualquier lugar
  11. Despliega a un entorno de staging y haz una prueba manual completa

Ese último paso parece obvio. Pero he visto que personas omitan staging e implementen directamente en producción en actualizaciones "pequeñas". Un cambio de comportamiento de almacenamiento en caché que hace que tu página principal golpee una API en vivo en cada solicitud no es algo pequeño.

---

FAQ

¿Es Next.js 16 lo suficientemente estable para producción?

Sí, para la mayoría de casos de uso. El cambio de Turbopack-para-desarrollo es el mayor cambio, y dado que las compilaciones de producción todavía usan Webpack, tu salida realmente desplegada se ve menos afectada que tu experiencia de desarrollo. Los cambios de comportamiento de almacenamiento en caché son la mayor preocupación de producción, y son directos de auditar si eres metódico al respecto.

¿Necesito actualizar React a 19 al mismo tiempo?

Técnicamente Next.js 16 soporta React 18 como mínimo, pero las nuevas características (como el hook use() estable y el cambio ref-as-prop) requieren React 19. Si estás en un proyecto con muchas dependencias de terceros, vale la pena verificar la compatibilidad antes de comprometerte con React 19 al mismo tiempo. La guía de actualización de React 19 vale la pena leer junto con la documentación de migración de Next.js.

Mi configuración personalizada de Webpack desapareció con Turbopack. ¿Qué hago?

Tu configuración de Webpack sigue ejecutándose durante next build. Para desarrollo, necesitas replicar las partes relevantes usando la clave turbopack en next.config.js. La sintaxis es diferente, especialmente para transformaciones de archivos y alias. Consulta la referencia oficial de configuración de Turbopack y espera gastar una o dos horas en esto si tu configuración de Webpack es compleja.

¿Qué tan más rápido es Turbopack realmente?

En los proyectos que he probado: el inicio en frío bajó de 12-18 segundos a 3-4 segundos. HMR en cambios de componentes pasó de 1-3 segundos a menos de 200ms en la mayoría de los casos. Estos son números aproximados y variarán según el tamaño del proyecto, pero la diferencia es notable en cualquier cosa más allá de un proyecto trivial.

---

La actualización vale la pena hacer. La velocidad de desarrollo de Turbopack por sí sola cambia cómo te sientes trabajando en una base de código Next.js grande. Solo entra con los ojos abiertos sobre los cambios de caché y las verificaciones de compatibilidad de bibliotecas de terceros, esas dos cosas son donde realmente va la mayor parte del tiempo.

Hazlo de un sitio a la vez. Yo lo hice.

← volver