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.

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.
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:
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.tsEl 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.
# Actualizar Nuxt y deduplicar dependencias
npx nuxt upgrade --dedupeDespués de actualizar el paquete, es necesario mover los archivos de la aplicación al directorio app/:
# Automatizar la reestructuración de directorios
npx codemod@latest nuxt/4/file-structureEste 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:
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.
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 refsdata,errorystatus. 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.
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.
<script setup lang="ts">
// Los datos ahora usan shallowRef por defecto
const { data: metrics } = await useFetch('/api/dashboard/metrics')
// La mutación directa de propiedades no activa la reactividad
// metrics.value.visits = 100 // No provocará un re-render
// Reemplazar el valor completo para activar las actualizaciones
metrics.value = { ...metrics.value, visits: 100 }
// O activar la reactividad profunda para esta llamada específica
const { data: settings } = await useFetch('/api/settings', {
deep: true,
})
</script>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.
¿Listo para aprobar tus entrevistas de Vue.js / Nuxt.js?
Practica con nuestros simuladores interactivos, flashcards y tests técnicos.
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:
{
"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:
# Antes (Nuxt 3)
nuxt prepare && vue-tsc --noEmit
# Después (Nuxt 4)
nuxt prepare && vue-tsc -b --noEmitOtro 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 <KeepAlive>, Vue DevTools y utilidades de testing.
<!-- app/pages/dashboard.vue -->
<template>
<NuxtPage :keepalive="{
include: ['DashboardMetricsCard', 'DashboardRecentActivity'],
}" />
</template>Los proyectos que utilizan <KeepAlive> 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:
<script setup lang="ts">
const route = useRoute()
const { data: product } = await useFetch(`/api/products/${route.params.id}`)
// Unhead v2: eliminación de vmid, hid, children, body
useSeoMeta({
title: () => product.value?.name ?? 'Product',
ogTitle: () => product.value?.name ?? 'Product',
description: () => product.value?.description ?? '',
ogImage: () => product.value?.imageUrl ?? '',
})
</script>Para proyectos que dependen de parámetros de template o el ordenamiento por alias, estas funcionalidades deben instalarse como plugins explícitos:
import { TemplateParamsPlugin, AliasSortingPlugin } from '@unhead/vue/plugins'
export default defineNuxtPlugin({
setup() {
const unhead = injectHead()
unhead.use(TemplateParamsPlugin)
unhead.use(AliasSortingPlugin)
},
})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 conuseNuxtApp().payload. Este objeto global se elimina después de la hidratación en Nuxt 4. - Hook
pages:extend: cambiar al nuevo hookpages:resolved, que se ejecuta después del escaneo de metadatos de páginas. - Booleano
dedupe: reemplazarrefresh({ dedupe: true })conrefresh({ dedupe: 'cancel' })yfalsecon'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 deundefined. UsarclearNuxtState('key', { reset: false })para el comportamiento anterior.
Una secuencia de migración práctica para aplicaciones en producción:
- Ejecutar
npx nuxt upgrade --dedupey verificar que la aplicación compile correctamente - Ejecutar el codemod:
npx codemod@latest nuxt/4/migration-recipe - Mover archivos a
app/(automatizado por el codemod file-structure) - Actualizar las verificaciones de
nullaundefineden la lógica de obtención de datos - Probar los componentes
<KeepAlive>con los nombres normalizados - Actualizar la verificación de tipos en CI para usar
vue-tsc -b --noEmit - 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 en SharpSkill, o revisar la guía de SSR y generación estática 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-recipeautomatiza la reestructuración de directorios, el reemplazo de APIs obsoletas y las actualizaciones de obtención de datos - La reactividad superficial mediante
shallowRefmejora 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
¡Empieza a practicar!
Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.
Etiquetas
Compartir
Artículos relacionados

Vue 3 Pinia vs Vuex: Gestión de Estado Moderna y Preguntas de Entrevista 2026
Comparación detallada entre Pinia y Vuex: diseño de API, soporte TypeScript, Composition API, rendimiento, estrategias de migración y preguntas frecuentes en entrevistas Vue para 2026.

Nuxt 3: SSR y generación estática, la guía completa
Domine el SSR y la generación estática con Nuxt 3. Desde useFetch hasta route rules, aprenda a optimizar el rendimiento de sus aplicaciones Vue.js.

Preguntas esenciales de Vue.js: 25 preguntas para conseguir el puesto
Prepara tu entrevista de Vue.js con estas 25 preguntas esenciales. Desde la reactividad hasta los composables, domina los conceptos clave para tu próxima entrevista.