# Nuxt 4 en 2026: nueva estructura de directorios y migración desde Nuxt 3 > Guía completa de migración a Nuxt 4: estructura de directorios app/, capa singleton de obtención de datos, mejoras en TypeScript e instrucciones paso a paso con ejemplos de código. - Published: 2026-05-01 - Updated: 2026-05-01 - Author: SharpSkill - Tags: nuxt, vue, migración, typescript, tutorial - Reading time: 8 min --- Nuxt 4 introduce una estructura de directorios rediseñada que separa el código de la aplicación de la configuración, junto con una capa singleton de obtención de datos, reactividad superficial por defecto y contextos TypeScript divididos. Lanzado en julio de 2025 y actualmente en la versión 4.4, esta actualización mayor se enfoca en la evolución más que en la revolución, haciendo que la ruta de migración desde Nuxt 3 sea considerablemente más fluida que el salto de Nuxt 2 a 3. > **Migración automatizada disponible** > > El equipo de Nuxt se asoció con Codemod para automatizar la mayoría de los pasos de migración. Basta con ejecutar `npx codemod@latest nuxt/4/migration-recipe` para gestionar la reestructuración de directorios, las actualizaciones de obtención de datos y los reemplazos de APIs obsoletas de forma automática. ## La nueva estructura del directorio app/ en Nuxt 4 Nuxt 4 traslada todo el código fuente de la aplicación a un directorio `app/` por defecto. Esta separación resuelve un problema real: los observadores de archivos en Linux y Windows funcionan significativamente mejor cuando el código de la aplicación reside en un subdirectorio dedicado en lugar de estar mezclado con `node_modules/`, `.git/` y archivos de configuración. La nueva organización sigue esta estructura: ```text my-nuxt-app/ ├─ app/ │ ├─ assets/ │ ├─ components/ │ ├─ composables/ │ ├─ layouts/ │ ├─ middleware/ │ ├─ pages/ │ ├─ plugins/ │ ├─ utils/ │ ├─ app.vue │ ├─ app.config.ts │ └─ error.vue ├─ content/ ├─ public/ ├─ shared/ # Nuevo: código compartido entre app y servidor ├─ server/ └─ nuxt.config.ts ``` El directorio `shared/` es una adición notable. Cualquier composable o utilidad ubicado en `shared/` se auto-importa tanto en la aplicación Vue como en el servidor Nitro, eliminando la necesidad de importaciones manuales al compartir esquemas de validación, definiciones de tipos o funciones utilitarias entre ambos contextos. ## Migración paso a paso de Nuxt 3 a Nuxt 4 El proceso de actualización comienza con un solo comando. Nuxt detecta la estructura plana existente y continúa funcionando sin ningún cambio, por lo que la migración puede realizarse de forma incremental. ```bash # Actualizar Nuxt y deduplicar dependencias npx nuxt upgrade --dedupe ``` Después de actualizar el paquete, es necesario mover los archivos de la aplicación al directorio `app/`: ```bash # Automatizar la reestructuración de directorios npx codemod@latest nuxt/4/file-structure ``` Este codemod mueve `assets/`, `components/`, `composables/`, `layouts/`, `middleware/`, `pages/`, `plugins/`, `utils/`, `app.vue`, `error.vue` y `app.config.ts` dentro de `app/`. Los archivos que pertenecen a la raíz — `nuxt.config.ts`, `server/`, `public/` y `content/` — permanecen en su lugar. Para proyectos que necesiten postergar la reestructuración, el directorio fuente puede configurarse explícitamente: ```typescript // nuxt.config.ts export default defineNuxtConfig({ srcDir: '.', dir: { app: 'app' }, }) ``` Esta configuración le indica a Nuxt 4 que resuelva los archivos desde la raíz del proyecto, replicando exactamente el comportamiento de Nuxt 3. ## Capa singleton de obtención de datos y claves reactivas Nuxt 4 cambia fundamentalmente la forma en que `useAsyncData` y `useFetch` gestionan los datos. Múltiples componentes que llaman a la misma clave ahora comparten una única referencia reactiva en lugar de mantener copias independientes. ```typescript // app/composables/useProductData.ts export function useProductData(productId: string) { return useAsyncData( `product-${productId}`, () => $fetch(`/api/products/${productId}`), { getCachedData: (key, nuxtApp, ctx) => { // ctx.cause indica la razón del fetch if (ctx.cause === 'refresh:manual') return undefined return nuxtApp.payload.data[key] }, }, ) } ``` Tres cambios destacan en esta nueva capa de datos: - **Referencias compartidas**: llamar a `useProductData('abc')` en dos componentes devuelve las mismas refs `data`, `error` y `status`. Actualizar una actualiza ambas. - **Limpieza automática**: cuando el último componente que usa una clave se desmonta, Nuxt libera los datos asociados de la memoria. - **Claves reactivas**: envolver una clave en un computed o ref dispara automáticamente un nuevo fetch cuando el valor cambia. El callback `getCachedData` ahora recibe un objeto de contexto con una propiedad `cause` (`'initial'`, `'refresh:hook'`, `'refresh:manual'` o `'watch'`), permitiendo un control granular sobre cuándo servir datos en caché versus obtener datos frescos. > **Valores por defecto modificados** > > Las propiedades data y error de `useAsyncData`/`useFetch` ahora tienen `undefined` como valor por defecto en lugar de `null`. Es necesario actualizar las verificaciones `=== null` a `=== undefined` o utilizar una comparación no estricta. ## Reactividad superficial por defecto para mejor rendimiento Nuxt 4 cambia `data` de `useAsyncData` y `useFetch` a `shallowRef` en lugar de `ref`. Vue ya no rastrea recursivamente cada propiedad anidada, lo que ofrece mejoras de rendimiento medibles para respuestas de API con objetos profundamente anidados o arrays grandes. ```typescript // app/pages/dashboard.vue ``` Para la mayoría de las visualizaciones de solo lectura (dashboards, listados de productos, páginas de artículos), la reactividad superficial funciona sin ningún cambio de código. La opción `deep: true` sigue disponible para formularios o interfaces interactivas que mutan propiedades anidadas directamente. ## División de contextos TypeScript y seguridad de tipos mejorada Nuxt 4 genera configuraciones TypeScript separadas para cada contexto del proyecto: - `.nuxt/tsconfig.app.json` — Código de la aplicación Vue - `.nuxt/tsconfig.server.json` — Código del servidor Nitro - `.nuxt/tsconfig.shared.json` — Utilidades compartidas - `.nuxt/tsconfig.node.json` — Configuración en tiempo de build Esta separación significa que el IDE ya no sugiere APIs exclusivas del servidor en el código del cliente, y viceversa. Un único `tsconfig.json` en la raíz del proyecto referencia las cuatro configuraciones: ```json { "files": [], "references": [ { "path": "./.nuxt/tsconfig.app.json" }, { "path": "./.nuxt/tsconfig.server.json" }, { "path": "./.nuxt/tsconfig.shared.json" }, { "path": "./.nuxt/tsconfig.node.json" } ] } ``` La verificación de tipos en CI también cambia. El comando `vue-tsc` ahora requiere la bandera `-b` (modo build) para procesar correctamente las referencias de proyecto: ```bash # Antes (Nuxt 3) nuxt prepare && vue-tsc --noEmit # Después (Nuxt 4) nuxt prepare && vue-tsc -b --noEmit ``` Otro cambio en TypeScript: `compilerOptions.noUncheckedIndexedAccess` está activado por defecto (`true`). Acceder a un elemento de array o propiedad de objeto por índice ahora devuelve `T | undefined`, capturando errores potenciales en tiempo de ejecución durante la compilación. ## Nombres de componentes normalizados y Vue Router v5 Nuxt 4.3 realizó la actualización a Vue Router v5, eliminando la dependencia de `unplugin-vue-router`. Para la mayoría de las aplicaciones, esta actualización es transparente. Las convenciones de nomenclatura de componentes están ahora estandarizadas. Un componente ubicado en `components/dashboard/MetricsCard.vue` obtiene el nombre `DashboardMetricsCard` de manera consistente en todos los contextos — incluyendo ``, Vue DevTools y utilidades de testing. ```vue ``` Los proyectos que utilizan `` con filtros de nombres de componentes deben actualizar los nombres para coincidir con esta nueva convención. El comportamiento anterior, donde el nombre podía variar según el contexto, ya no aplica. ## Gestión de cambios importantes en el manejo del head Nuxt 4 incluye Unhead v2, que elimina varias propiedades obsoletas de `useHead` y `useSeoMeta`: ```typescript // app/pages/product/[id].vue ``` Para proyectos que dependen de parámetros de template o el ordenamiento por alias, estas funcionalidades deben instalarse como plugins explícitos: ```typescript // app/plugins/unhead.ts import { TemplateParamsPlugin, AliasSortingPlugin } from '@unhead/vue/plugins' export default defineNuxtPlugin({ setup() { const unhead = injectHead() unhead.use(TemplateParamsPlugin) unhead.use(AliasSortingPlugin) }, }) ``` > **Línea de tiempo de soporte de Nuxt 3** > > Nuxt 3 continúa recibiendo actualizaciones de seguridad y correcciones de errores críticos hasta el 31 de julio de 2026. Después de esa fecha, Nuxt 3 dejará de tener soporte. Planificar la migración ahora evita ejecutar aplicaciones en producción sobre un framework sin mantenimiento. ## Lista de verificación de migración y errores comunes El codemod automatizado gestiona la mayoría de los cambios, pero varios elementos requieren atención manual: - **Eliminación de `window.__NUXT__`**: reemplazar con `useNuxtApp().payload`. Este objeto global se elimina después de la hidratación en Nuxt 4. - **Hook `pages:extend`**: cambiar al nuevo hook `pages:resolved`, que se ejecuta después del escaneo de metadatos de páginas. - **Booleano `dedupe`**: reemplazar `refresh({ dedupe: true })` con `refresh({ dedupe: 'cancel' })` y `false` con `'defer'`. - **Estilos inline**: solo los estilos de componentes Vue se incluyen inline por defecto; el CSS global se carga como archivos separados. Agregar `features: { inlineStyles: true }` para restaurar el comportamiento de Nuxt 3. - **`clearNuxtState`**: ahora restablece a los valores iniciales en lugar de `undefined`. Usar `clearNuxtState('key', { reset: false })` para el comportamiento anterior. Una secuencia de migración práctica para aplicaciones en producción: 1. Ejecutar `npx nuxt upgrade --dedupe` y verificar que la aplicación compile correctamente 2. Ejecutar el codemod: `npx codemod@latest nuxt/4/migration-recipe` 3. Mover archivos a `app/` (automatizado por el codemod file-structure) 4. Actualizar las verificaciones de `null` a `undefined` en la lógica de obtención de datos 5. Probar los componentes `` con los nombres normalizados 6. Actualizar la verificación de tipos en CI para usar `vue-tsc -b --noEmit` 7. Ejecutar la suite completa de tests y corregir los errores de TypeScript expuestos por `noUncheckedIndexedAccess` Para profundizar en los conceptos de Vue y Nuxt, es posible explorar las [preguntas de entrevista Vue/Nuxt](/technologies/vue-nuxt/interview-questions/nuxt-fundamentals) en SharpSkill, o revisar la [guía de SSR y generación estática](/blog/vue-nuxt/nuxt-3-ssr-static-generation) para obtener contexto sobre estrategias de renderizado que también aplican en Nuxt 4. ## Conclusión - Nuxt 4.4 (versión actual a abril de 2026) estabiliza la estructura del directorio `app/`, la obtención de datos singleton y los contextos TypeScript divididos como valores predeterminados listos para producción - El comando `npx codemod@latest nuxt/4/migration-recipe` automatiza la reestructuración de directorios, el reemplazo de APIs obsoletas y las actualizaciones de obtención de datos - La reactividad superficial mediante `shallowRef` mejora el rendimiento de las páginas de solo lectura sin requerir cambios de código en la mayoría de los casos - Las configuraciones TypeScript separadas por contexto (app, server, shared, node) eliminan las filtraciones de tipos entre contextos y mejoran el autocompletado del IDE - Nuxt 3 alcanza su fin de vida el 31 de julio de 2026 — migrar antes de esa fecha garantiza que las aplicaciones funcionen sobre una versión soportada y mantenida activamente - Vue Router v5 y Unhead v2 ofrecen APIs más limpias a costa de eliminar propiedades obsoletas que deben auditarse durante la migración --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/es/blog/vue-nuxt/nuxt-4-directory-structure-migration