Gabriel Caiana

Nuxt 4: New Directory Structure and Migration Guide


Table of contents
  1. 🧭 Quick Navigation Guide
  2. πŸ”„ Nuxt 3 vs Nuxt 4 Comparison
  3. Old Framework (Nuxt 3)
  4. New Framework (Nuxt 4)
  5. 🎯 Benefits of the New Structure
  6. 1. Best File Watching Performance
  7. 2. Clear Separation of Responsibilities
  8. 3. Best Organization for Large Projects
  9. πŸš€ Automatic Migration
  10. Using the Upgrade Command
  11. What the Command Does Automatically
  12. πŸ”§ Manual Migration
  13. Step by step
  14. Update Imports
  15. βš™οΈ Nuxt 4 Configuration
  16. Basic Configuration
  17. Advanced Configuration
  18. πŸ’‘ Practical Examples
  19. Example of Optimized Organization
  20. Project Structure Example
  21. 🚨 Common Problems and Solutions
  22. 1. Broken Imports
  23. 2. Assets Not Found
  24. 3. Build Settings
  25. πŸ” Migration Check
  26. Verification Checklist
  27. Verification Commands
  28. 🎯 Next Steps
  29. ✨ 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

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 code
  • server/: Server logic and APIs
  • shared/: Code shared between client and server
  • public/: 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

  1. Moves directories to the new app/ structure
  2. Updates settings on nuxt.config.ts
  3. Adjusts imports and path references
  4. 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.ts has 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:

  1. Explore the new caching system - Read the article about Data Fetching and Cache
  2. Learn about Type Safety - Read the article about TypeScript
  3. 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: