Provide clarification for nuxt 4 directory structure

I don't quite understand the directory structure. More specifically, how are the plugins, and modules folders shared betwee app and server? If I want to create a new custom module that works on both app and server side, should I create a shared folder, then a modules folder? It would be easier to just have a root level modules folder.
11 Replies
kapa.ai
kapa.ai4mo ago
Hi @Thick Black W. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Certainly! Here’s a clarification of the Nuxt 4 directory structure, focusing on the roles of the plugins, modules, and shared folders, and how to structure a custom module that works on both the app and server sides. --- Nuxt 4 Directory Structure Overview In Nuxt 4, the default structure is:
app/
assets/
components/
composables/
layouts/
middleware/
pages/
plugins/
utils/
app.vue
...
modules/
public/
shared/
server/
api/
middleware/
plugins/
routes/
utils/
nuxt.config.ts
app/
assets/
components/
composables/
layouts/
middleware/
pages/
plugins/
utils/
app.vue
...
modules/
public/
shared/
server/
api/
middleware/
plugins/
routes/
utils/
nuxt.config.ts
- app/ contains all your client-side (Vue app) code. - server/ contains server-side code (API routes, middleware, Nitro plugins, etc.). - modules/ is for local Nuxt modules (these can register code for both app and server). - shared/ is for code (like utilities and types) that needs to be used in both the app and server contexts, but cannot import Vue or Nitro-specific code Docs: shared. --- Plugins - app/plugins/ is for Nuxt plugins that run in the Vue app context. You can use .server or .client suffixes to restrict plugins to server or client only, but these are still Vue app plugins, not Nitro/server plugins Docs: plugins. - server/plugins/ is for Nitro plugins, which extend the server runtime (Nitro) and are not available in the Vue app context Docs: server. They are not shared between app and server. Each context has its own plugin system. --- Modules - The root-level modules/ folder is for local Nuxt modules. These modules can register code for both the app and server sides, depending on how you implement them. You do not need to create separate modules folders for app and server—just use the root-level one Docs: modules. - Modules can inject plugins, add server handlers, and more, so they are the right place for code that needs to affect both sides. --- Shared Folder - The shared/ folder is for utilities and types that need to be used in both the app and server, but cannot import Vue or Nitro code. Only shared/utils/ and shared/types/ are auto-imported; other files must be imported manually using the #shared alias Docs: shared. - Use this for pure JavaScript/TypeScript code that is context-agnostic. --- Creating a Custom Module for Both App and Server - Use the root-level modules/ folder. Your module can register plugins for the app, add server handlers, and more. - If you need to share utility code between app and server, put that code in shared/ and import it in your module or plugins as needed. You do not need to create a modules folder inside shared/ or vice versa. The root-level modules/ is the standard and recommended approach. --- #### Example Structure
modules/
my-module/
index.ts // Nuxt module entry point
runtime/
plugin.ts // App plugin (if needed)
api-route.ts // Server handler (if needed)
shared/
utils/
my-util.ts // Shared utility
modules/
my-module/
index.ts // Nuxt module entry point
runtime/
plugin.ts // App plugin (if needed)
api-route.ts // Server handler (if needed)
shared/
utils/
my-util.ts // Shared utility
--- Summary:
- Use modules/ at the root for custom modules that affect both app and server. - Use shared/ for utilities/types needed in both contexts. - Plugins are context-specific: app/plugins/ for Vue app, server/plugins/ for Nitro/server. For more details, see the Nuxt 4 Upgrade Guide and Directory Structure documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4mo ago
<@1321238874634195004> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
JanH-BE
JanH-BE4mo ago
And where do you put the <i18n> folder? In the app/i18n/locales/en/main.json folder or in the root i18n/locales/en/main.json ?
Hugo
Hugo4mo ago
The modules folder should be located at the root of your project
Alaki
Alaki4mo ago
I prefer app folder: In the app/i18n/locales/en/main.json
Dante
Dante4w ago
@kapa.ai following up on this. Where would i put a lib folder with nuxt 4
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- In Nuxt 4, you can create a custom lib/ folder at the project root if you want to organize arbitrary utility code or libraries. Nuxt does not reserve or auto-import from a lib/ folder by default, so you will need to import files from it manually in your code. This approach is supported and commonly used for code that doesn't fit into the standard Nuxt folders like shared/, composables/, or utils/ Stack Overflow example. However, be aware that only certain folders (like shared/, composables/, and utils/) are auto-imported by Nuxt. If you use a custom lib/ folder, you must handle imports yourself, or configure auto-imports in your nuxt.config.ts if desired Stack Overflow example. Summary:
- You can place a lib/ folder at the root of your Nuxt 4 project. - Files in lib/ are not auto-imported; you must import them manually or configure auto-imports. - This is a valid and supported approach for organizing custom utilities or libraries. If you want your utilities to be auto-imported and available in both app and server contexts, consider using the shared/ folder instead, following Nuxt 4 conventions docs: shared directory. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@332238302457495564> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Dante
Dante4w ago
@kapa.ai my lib folder is meant to have code like this
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";

export const auth = betterAuth({
database: new Database("./sqlite.db"),
});
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";

export const auth = betterAuth({
database: new Database("./sqlite.db"),
});
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on your example, your lib folder contains code that initializes third-party libraries and exports configured instances (e.g., authentication and database clients). In Nuxt 4, there is no reserved or special treatment for a lib/ folder—placing such code in a custom lib/ directory at the project root is a valid and supported approach. However, Nuxt will not auto-import from this folder, so you will need to import these utilities manually wherever you need them. This pattern is commonly used for code that doesn't fit into Nuxt's auto-imported directories like composables/, utils/, or shared/. For example, a Stack Overflow answer demonstrates placing a utility function in a lib/ folder and manually importing it in components or server routes, which works well for code like your example that initializes and exports service instances (Stack Overflow example). Key points: - You can safely create a lib/ folder at the root of your Nuxt 4 project for this purpose. - Files in lib/ are not auto-imported; you must import them manually. - This is a standard and supported approach for organizing such code in Nuxt 4. If you want auto-imports or need to share pure utilities between app and server, consider the shared/ directory, but for code that initializes external libraries (especially those that may be server-only), a custom lib/ folder is appropriate. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@332238302457495564> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?