Nuxt 4 organises a project into three worlds: app/ (the Vue frontend), server/ (the Nitro backend), and shared/ (code used by both). Most architecture mistakes come from putting code in the wrong world. Here are the rules.
Split code by context
Structure the project so each layer has a single responsibility:
app/— everything Vue: components, pages, composables, layouts, frontend utilities.server/— API routes, middleware, server utilities.shared/— code common to both app and server.
What belongs in shared/
Only universal code that does not depend on the browser or on Node.js: formatters, validators, status maps, pure helpers, and shared TypeScript types. If a function touches window, document, cookies, or runtimeConfig, it does not belong in shared/.
shared/utils— pure functions (formatting, calculations, mappers).shared/types— interfaces and types used across contexts, e.g. aUsershape consumed by both the UI and the API.
Where to put frontend code
app/utils— frontend-specific utilities (DOM helpers, browser APIs, formatting tied to the UI).app/composables— only Vue Composition logic (reactive state,useXhooks). Do not dump plain helpers here.
Where to put backend code
server/utils — server-only logic: database access, secret handling, third-party API calls. This code must never reach the client bundle.
Auto-import: know its reach
Nuxt 4 auto-imports from app/composables, app/utils, and server/utils. Crucially, shared/ is not auto-imported — you import it explicitly. That explicit boundary is a feature: it stops shared code from silently coupling to a single context.
Never mix frontend and backend
Keep these apart in the same file at your peril: window, DOM APIs and localStorage are client-only; database clients, secrets and Node modules are server-only. shared/ is for what is safe in both.
The practical rule
Before creating a file, ask three questions: Does it need the browser? Does it need the server? Is it pure? The answer tells you whether it lives in app/, server/, or shared/. Clear structure, predictable auto-import, no leaks between client and server — that is a Nuxt 4 codebase that scales.


