Nuxt 4: New Directory Structure and Migration Guide
Table of contents
- π§ Quick Navigation Guide
- π Nuxt 3 vs Nuxt 4 Comparison
- Old Framework (Nuxt 3)
- New Framework (Nuxt 4)
- π― Benefits of the New Structure
- 1. Best File Watching Performance
- 2. Clear Separation of Responsibilities
- 3. Best Organization for Large Projects
- π Automatic Migration
- Using the Upgrade Command
- What the Command Does Automatically
- π§ Manual Migration
- Step by step
- Update Imports
- βοΈ Nuxt 4 Configuration
- Basic Configuration
- Advanced Configuration
- π‘ Practical Examples
- Example of Optimized Organization
- Project Structure Example
- π¨ Common Problems and Solutions
- 1. Broken Imports
- 2. Assets Not Found
- 3. Build Settings
- π Migration Check
- Verification Checklist
- Verification Commands
- π― Next Steps
- β¨ Conclusion
Nuxt 4 brings one of the most significant changes in its history: a complete reorganization of the directory structure. The new structure with the app/ directory is not just a cosmetic change - it is an architectural redesign that improves the performance, organization and scalability of projects.
π§ Quick Navigation Guide
ποΈ Structure and Organization
- Nuxt 3 vs Nuxt 4 Comparison
- Benefits of the New Structure
- Automatic Migration
- Manual Migration
- Nuxt 4 Configuration
- Practical Examples
π Nuxt 3 vs Nuxt 4 Comparison
Old Framework (Nuxt 3)
my-nuxt-app/
βββ components/ # Vue components
βββ layouts/ # Application layouts
βββ pages/ # Pages/routes
βββ plugins/ # Vue plugins
βββ middleware/ # Route middleware
βββ composables/ # Vue composables
βββ utils/ # Utility functions
βββ server/ # API and server handlers
βββ public/ # Static assets
βββ .nuxt/ # Generated files
βββ app.vue # Root component
βββ nuxt.config.ts # Configuration
New Framework (Nuxt 4)
my-nuxt-app/
βββ app/ # π New main directory
β βββ components/ # Vue components
β βββ layouts/ # Application layouts
β βββ pages/ # Pages/routes
β βββ plugins/ # Vue plugins
β βββ middleware/ # Route middleware
β βββ composables/ # Vue composables
β βββ utils/ # Utility functions
β βββ assets/ # π Organized assets
β β βββ css/ # Styles
β β βββ images/ # Images
β β βββ fonts/ # Fonts
β βββ app.vue # Root component
βββ server/ # API and server handlers
βββ shared/ # π Shared code
βββ public/ # Static assets
βββ .nuxt/ # Generated files
βββ nuxt.config.ts # Configuration
π― Benefits of the New Structure
1. Best File Watching Performance
The new framework optimizes Chokidarβs file watching capabilities, providing a clear distinction between code that executes in the application.
// nuxt.config.ts - Optimized configuration
export default defineNuxtConfig({
// π Automatically enables the new structure
future: {
compatibilityVersion: 4
},
// π Better asset organization
css: [
'~/app/assets/css/main.css',
'~/app/assets/css/components.css'
],
// π More efficient auto-imports
imports: {
dirs: [
'app/composables',
'app/utils',
'shared/utils'
]
}
})
2. Clear Separation of Responsibilities
app/: Application-specific codeserver/: Server logic and APIsshared/: Code shared between client and serverpublic/: Public static assets
3. Best Organization for Large Projects
The structure facilitates organization in projects with multiple teams and complex functionalities.
π Automatic Migration
Using the Upgrade Command
# π Automatic migration to Nuxt 4
npx nuxi@latest upgrade --force
# Check whether migration succeeded
npx nuxi@latest info
What the Command Does Automatically
- Moves directories to the new
app/structure - Updates settings on
nuxt.config.ts - Adjusts imports and path references
- Checks compatibility of dependencies
π§ Manual Migration
Step by step
# 1. Create new structure
mkdir app
mkdir shared
# 2. Move main directories
mv components app/
mv layouts app/
mv pages app/
mv plugins app/
mv middleware app/
mv composables app/
mv utils app/
mv app.vue app/
# 3. Move assets (if they exist)
mkdir -p app/assets/css
mkdir -p app/assets/images
mkdir -p app/assets/fonts
# 4. Move style files
mv assets/css/* app/assets/css/ 2>/dev/null || true
mv assets/images/* app/assets/images/ 2>/dev/null || true
mv assets/fonts/* app/assets/fonts/ 2>/dev/null || true
# 5. Clean empty directories
rmdir assets 2>/dev/null || true
Update Imports
// β Before (Nuxt 3)
import { useMyComposable } from '~/composables/useMyComposable'
import { formatDate } from '~/utils/date'
// β
After (Nuxt 4)
import { useMyComposable } from '~/app/composables/useMyComposable'
import { formatDate } from '~/app/utils/date'
// π Ou usar auto-imports (recomendado)
// Imports are automatic based on configuration
βοΈ Nuxt 4 Configuration
Basic Configuration
// nuxt.config.ts
export default defineNuxtConfig({
// π Ativa a nova estrutura
future: {
compatibilityVersion: 4
},
// π Directory configuration
dir: {
// Default directories (optional, already auto-configured)
pages: 'app/pages',
components: 'app/components',
layouts: 'app/layouts',
plugins: 'app/plugins',
middleware: 'app/middleware',
composables: 'app/composables',
utils: 'app/utils'
},
// π Optimized auto-imports
imports: {
dirs: [
'app/composables',
'app/utils',
'shared/utils'
]
},
// π CSS organizado
css: [
'~/app/assets/css/main.css',
'~/app/assets/css/tailwind.css'
]
})
Advanced Configuration
// nuxt.config.ts - Advanced configuration
export default defineNuxtConfig({
future: {
compatibilityVersion: 4
},
// π Better asset organization
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "~/app/assets/scss/variables.scss";'
}
}
}
},
// π Auto-imports com aliases
imports: {
dirs: [
'app/composables',
'app/utils',
'shared/utils'
],
global: true
},
// π Optimized build configuration
build: {
transpile: ['vue-toastification']
}
})
π‘ Practical Examples
Example of Optimized Organization
// app/components/ui/Button.vue
<template>
<button
:class="buttonClasses"
@click="handleClick"
>
<slot />
</button>
</template>
<script setup lang="ts">
// π Auto-import de utils do app/
const { generateButtonClass } = useButtonUtils()
// π Auto-import de composables
const { trackButtonClick } = useAnalytics()
interface Props {
variant: 'primary' | 'secondary' | 'danger'
size: 'sm' | 'md' | 'lg'
disabled?: boolean
}
const props = withDefaults(defineProps<Props>(), {
variant: 'primary',
size: 'md',
disabled: false
})
const buttonClasses = computed(() =>
generateButtonClass(props.variant, props.size, props.disabled)
)
const handleClick = () => {
if (!props.disabled) {
trackButtonClick(props.variant)
}
}
</script>
Project Structure Example
// Recommended structure for large projects
my-nuxt-app/
βββ app/
β βββ components/
β β βββ ui/ # Base components (Button, Input, etc.)
β β βββ forms/ # Form components
β β βββ layout/ # Layout components
β βββ composables/
β β βββ useAuth.ts # Authentication
β β βββ useApi.ts # API calls
β β βββ useCache.ts # Cache management
β βββ utils/
β β βββ date.ts # Date utilities
β β βββ validation.ts # Validations
β β βββ formatting.ts # Formatting
β βββ assets/
β βββ css/
β β βββ main.css
β β βββ variables.css
β β βββ components.css
β βββ images/
βββ shared/
β βββ types/ # Shared types
β βββ constants/ # Constantes
β βββ utils/ # Shared utilities
βββ server/
βββ api/ # API routes
βββ middleware/ # Server middleware
βββ plugins/ # Server plugins
π¨ Common Problems and Solutions
1. Broken Imports
// β Common error after migration
import { something } from '~/components/Something'
// β
Solution
import { something } from '~/app/components/Something'
// π Ou melhor ainda, usar auto-imports
// The component will be imported automatically
2. Assets Not Found
// β Caminho antigo
background-image: url('~/assets/images/hero.jpg')
// β
New path
background-image: url('~/app/assets/images/hero.jpg')
3. Build Settings
// β Old configuration
css: ['~/assets/css/main.css']
// β
New configuration
css: ['~/app/assets/css/main.css']
π Migration Check
Verification Checklist
- All directories moved to
app/ - Imports have been updated
- Assets are on the correct paths
-
nuxt.config.tshas been updated - Application starts without errors
- Build works correctly
- Auto-imports work
Verification Commands
# Verify structure
tree app/ -I node_modules
# Verify build
npm run build
# Verify dev
npm run dev
# Verify types
npm run typecheck
π― Next Steps
After migrating the directory structure, you can:
- Explore the new caching system - Read the article about Data Fetching and Cache
- Learn about Type Safety - Read the article about TypeScript
- Optimize performance - Read the article about Performance
β¨ Conclusion
Nuxt 4βs new directory structure represents a significant evolution in project organization. Although the migration may seem complex initially, the benefits in terms of performance, organization and scalability make it worth the effort.
The app/ framework isnβt just a cosmetic change - itβs an architectural overhaul that prepares your projects for the future of web development.
π Official Resources: