Introduction and Purpose
Hey everybody, welcome back to another video on this channel. Yes, the mic is here; the sound is better, I hope. Right in the comments if not. Today we will have a look at the new improved directory structure of Nuxt 4: why it is there, how to migrate over, and can you keep the old one. All these answers right now.
Context: Nuxt 4 & Migration Reassurance
Go. Nuxt 4 is taking more and more shape and I hope you're not afraid of the migration because, well, I'm not. Lots of people around me are not because it will just be a few tiny breaking changes, nothing as big as Nuxt 2 to Nuxt 3. Don't worry. You can opt into them already as I've shown you in a video a few weeks ago; link as usual in the description up there. Today we have a look at the new directory structure that Nuxt 4 brings with it: why the Nuxt team decided to change things up, the benefits of it, and whether you can keep the old one or not.
Demo Project Setup and Version Check
So let's jump into the demo application and have a look. As usual the demo application is pretty minimal but there are a few things: we have our next.config, some things in server as shown in the last video, and some pages. If you haven't watched the last video about dynamic rendering, don't worry — this is just a good example to see how we migrate. We start with the most important thing first: we want to check if we are Nuxt 3.12 or higher. Nuxt 4 probably, but 3.12 is required; otherwise you have to use the nightly mode. We can use pnpm nuxt to figure it out and it says Nuxt 3.12, so we're good. Now we can start the server as usual, pnpm dev or whatever package manager you use, and it will just start 3.12.
Opting Into Compatibility Version 4
Now we want to opt into the changes as I've shown you a couple weeks ago by setting the future object in next.config and the compatibility version flag to 4 as a number. We save and see the validation running with compatibility version 4. Now we can opt into the new directory structure.
You see there's no error thrown saying you're doing things wrong or there's a new structure, mainly because we make sure you can keep your old projects without immediately migrating. You don't have to adapt to the new structure now. If you have a top-level pages folder, that's fine; Nuxt will fall back to the old structure. But we will migrate to see what the new structure brings.
Creating the app Source Directory
The first thing we want to do is create a new folder called app. All our Nuxt-specific things will live in this app folder: components, pages, and so on. Now we have app/pages and, for example, users within it. Technically, if you have a components folder it would also live here, e.g. components/my-component.vue. The same applies to middleware, layouts, and app.vue — app.vue will also live in the app folder. This might look strange, like app/app.vue, but naming is hard and there was an RFC to think about a readable name. Eventually we landed on app because other names like UI, web, front-end, Nuxt and Nitro felt off.
Customizing the Source Directory
You can customize the name. If app is not a nice name for you, name it my-fancy-app and point sourceDir in next.config to that folder. Save, wait for Nuxt to restart, and refresh the browser — it's still working as expected.
Recommendation on Defaults and Flexibility
I always recommend sticking with the recommendations unless you have a good reason not to, but if you want different naming because of internal structures you can do it. Nuxt gives freedom of choice while offering good defaults.
What Belongs Outside app: server Folder
Now, what might not belong in that app folder and are there other folders to consider? The server folder I never moved out. With the new structure we have the Nuxt front-oriented part and the server part, which consists of API routes, server routes, Nitro middleware, Nitro plugins, and so on. The idea is to have them in two separate folders for clarity.
Reasons for Separating server and app
There are a bunch of reasons. First, it's nice to separate the front-end part from the server part to avoid accidental imports from server code that you shouldn't do. For example, Vue composables shouldn't be used on the server. This separation reduces friction and makes it clearer which part is which, including server rendering concerns.
Another reason is performance. If you watch the whole project root, file watchers must monitor many nested files like .git and node_modules. On Linux and Mac this mostly works, but on Windows it caused severe performance issues during dev. File watching is only during dev, but a poor dev experience is painful. That's why we suggest having usually one folder called app and one called server, separated.
Top-level Folders: public and types
There are top-level folders that will stay. One is public. If you have public/test.txt, it maps to the domain root, so localhost:3000/test.txt serves that file. Public doesn't belong to Nuxt or Nitro specifically, so it makes sense to keep it at the root. You can also create other top-level folders, for example types that apply to both server and app parts.
Modules Folder and Automatic Registration
There's also a modules folder. Nuxt can automatically register modules placed in a modules folder; this works in Nuxt 3 right now without any compatibility flag. That folder can contain server middleware like Nitro things or Nuxt-specific modules, so it sits at the root as well.
New in Nuxt 4: Layers Folder
There's one more folder that's new and only possible with the Nuxt 4 compatibility flag: the layers folder. If you haven't heard of Layers, check the layers beginner guide video. The idea is to extract parts of an application into mini-applications or build on top of a base app. Layers are great for different designs, multi-tenant setups, or domain-driven design.
Demonstrating Layers: Create a Layer
Let's create a layers folder and inside add my-awesome-layer. Add a nuxt.config and a components/layer-component.vue file with an H1 saying 'Hey from layer'. Save and use that component from our app's pages/index.vue. Refresh and you will see 'Hey from layer'. You can override layer components in the main application. You don't need an entry in nuxt.config.ts to use layers; they can be very convenient.
Why Layers Matter
If you wondered why there's a component in a layer and how that makes sense, check the layers video — it's worth it. Layers is a feature that I don't think any other meta-framework has in the same way and it makes maintaining design systems or slicing up a big monolith really easy.
Official Upgrade Guide and Migration Notes
Have a look at the official upgrade guide for Nuxt 4 where the directory structure is mentioned. Migrating to the new structure has a significant impact but it's recommended and worth it. The RFC link and the source directory explanation are in the guide. Nuxt 3's source directory is now called app, but you can rename it via sourceDir. Modules and public remain in the root.
Clarifying Existing app Folder Usage
You might already have an app folder in your Nuxt application from before. That older app folder commonly contains router.options.ts or an SPA loading template. Those files are mentioned in the upgrade guide and commonly belong to the source directory now, so you can put them in app. If you prefer, you can configure a different directory via next.config's directories option like appOptions or appExtras.
Adjusting Aliases and Auto Imports
If you're not using auto imports and use aliases like the tilde or @, you might have to change them. Previously tilde and double-tilde or single-@ and double-@ pointed to the same place. Now the double tilde or double @ points to the project root and the single tilde or single @ points to the app folder (or whatever you named it). That means you might need to rename imports if you're importing a type from a top-level folder; use the double alias. You'll notice quickly because your IDE, type checks, or the build will complain if it can't find a file.
Final Recommendation and Migration Summary
That's basically all about the new improved directory structure. You don't have to opt in right away, but I highly recommend it for performance gains during dev, IDE type safety, and better type checks. This split structure is a start and we might add more features. You can rename things as you want. There's a bigger migration guide in the upgrade guide on nuxt.com showing exactly how to move assets, components, and composables into the app folder with an exhaustive checklist.
Outro and Links
Let me know what you think about the new directory structure. Is it good? Do you like it better than before? Better name for app? Bring them all in. I'm curious to read them and will answer. Don't forget to check out the newest Deja Vu app episode with Daniel Roe talking about Nuxt 4 changes and his journey. Check other videos and links everywhere, and stay tuned — next week there's another video coming. Thanks a lot for watching, let me know what you're missing or want to know, and stay tuned. Happy hacking.