Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Nuxt 4.0, announced July 15, 2025, is a stability-focused major release that changes defaults and clarifies boundaries between application, server, shared, and build-time code. Its most visible shifts are an optional app/ directory layout, shared and more explicitly reactive data-fetching behavior, and separate generated TypeScript configurations for different parts of a project. Existing projects do not have to adopt the new directory layout, but upgrading is a good time to review matching data-fetching keys, nested data mutations, type augmentations, and module compatibility. Nuxt describes the release as a set of thoughtful breaking changes intended to improve the development experience.

What’s new in Nuxt 4?

Nuxt 4 focuses on stability and developer experience rather than requiring every application to be reorganized. The changes most likely to affect day-to-day work are where Nuxt expects application code to live, how matching useAsyncData and useFetch calls share state, and how TypeScript configuration is scoped to code contexts.

  • Project organization: New projects use app/ for application code by default, while server and shared code remain distinct.
  • Data fetching: Calls with the same key share data, error, and status refs. Returned data is shallowly reactive by default.
  • TypeScript: Nuxt generates separate configurations for app, server, node/build-time, and shared code.

These are documented behavior changes, not a guarantee that every project will see a particular performance or productivity gain. Nuxt’s release announcement and Nuxt 4 upgrade guide provide the implementation details.

Do I need to move my project into an app/ directory?

No. Nuxt 4 uses app/ as the default home for application code, but the new layout is optional for existing projects. Nuxt detects an existing project structure and continues to support it; migration is a choice, not a prerequisite for using Nuxt 4.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What goes in app/?

The announced layout groups the client-facing application files under app/, including assets, components, composables, layouts, middleware, pages, plugins, utils, app.vue, app.config.ts, and error.vue. Other directories and configuration remain at the project root:

  • server/ for server-side code
  • shared/ for code shared across contexts
  • content/ and public/
  • nuxt.config.ts

Why introduce the boundary?

Nuxt says separating application code from directories such as node_modules/ and .git/ can help file watchers, particularly on Windows and Linux, and can make it clearer to IDEs whether code belongs to the client or server. Treat those as design goals rather than a promise of a measurable improvement in every setup.

If you keep your current layout, there is no need to move files just to match the new default. If you choose to reorganize, follow the upgrade guide and check any custom paths or modules that assume a particular directory structure.

Rank #2
TypeScript Programming Language - Software Engineer & Coder T-Shirt
  • TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
  • TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
  • Lightweight, Classic fit, Double-needle sleeve and bottom hem

What changed in Nuxt 4 data fetching?

In Nuxt 4, useAsyncData and useFetch calls that use the same key share their data, error, and status refs. This makes a key a shared identity for the fetched state, not merely a label attached to one call.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep calls that share a key compatible

Calls using a shared key should agree on behavior-affecting options. In particular, mismatched deep, transform, pick, getCachedData, or default options can produce warnings or unexpected results because those calls are addressing shared state. Review repeated calls to the same endpoint or resource and make their options consistent where they use the same key.

getCachedData can be called for watcher-driven and refreshNuxtData fetches; it receives request-cause context. That matters if custom caching logic treats an initial request differently from a refresh or another cause.

Reactive keys can trigger a new fetch

A key may be a computed ref, ref, or getter function. When a reactive key changes, Nuxt can fetch again and store the result separately under the new key. This is useful when the requested data depends on changing inputs, such as a selected record, but the key should represent the resource whose state is being shared.

Nested mutations are no longer reactive by default

Data returned by these composables is a shallow ref by default. Replacing the returned value remains reactive, but mutating a nested property does not itself trigger updates. If a component or composable relies on nested mutation causing a view update, review that code and opt into deep: true where deep reactivity is required. This is a compatibility check, not a requirement to change every fetch call.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Nuxt also removes shared data when the last component consuming it unmounts. The shared state therefore follows active consumers rather than necessarily remaining indefinitely after every consumer has gone away. These behaviors are detailed in the Nuxt 4 upgrade guide.

Do not generalize the later 39% bundle-size result

Nuxt’s October 25, 2025 announcement reported a 39% JavaScript bundle-size reduction after testing experimental async-data handler extraction on a previous version of nuxt.com. That result describes one site and one experiment; it is not a general benchmark for Nuxt 4.0 or a promise that another application will achieve the same reduction. Nuxt 4.2 announcement

How does Nuxt 4 change TypeScript support?

Nuxt generates distinct TypeScript configurations so the editor and type checker can treat app, server, build-time, and shared code as separate contexts. The generated files are:

  • .nuxt/tsconfig.app.json
  • .nuxt/tsconfig.server.json
  • .nuxt/tsconfig.node.json
  • .nuxt/tsconfig.shared.json

The legacy .nuxt/tsconfig.json remains available for backward compatibility. Existing projects extending it can continue to do so; adopting the project-reference setup is a separate decision. Nuxt’s intent with the more specific configurations is to scope available globals and APIs to the relevant context and improve type inference and IDE feedback.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Where should type augmentations go?

If you adopt project references, place app, server, and shared type augmentations in the directory that matches the code context they extend. A declaration in the wrong context may not be visible where expected under the more narrowly scoped setup. Check the Nuxt TypeScript guide alongside the upgrade guide before changing augmentation locations or CI type-check commands.

What to expect when checking types

The new setup may surface type issues that were previously hidden by a broader configuration. Treat those as issues to investigate in the relevant context; do not assume every newly reported error means the application has a runtime defect. Confirm that the project’s generated configuration, augmentation locations, and CI command are aligned with the setup it uses.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How should you approach a Nuxt 4 upgrade?

Start with the migration guide and evaluate the changes that apply to your project rather than performing a directory move by default. Nuxt recommends reviewing the upgrade guide and running npx nuxt upgrade --dedupe; it also offers a Codemod migration recipe as an option. Codemods do not guarantee that every project-specific change or module issue will be handled automatically.

  1. Review the migration guide. Identify breaking changes relevant to your Nuxt version, directory layout, and modules: Nuxt 4 upgrade guide.
  2. Upgrade and deduplicate. Run npx nuxt upgrade --dedupe as recommended by Nuxt, then review the resulting dependency changes.
  3. Check data-fetching keys. Find calls sharing keys and compare their relevant options. Check whether any code mutates nested fetched data and needs deep: true.
  4. Decide whether to adopt app/. Keep a supported existing structure or migrate deliberately, checking custom paths and module assumptions.
  5. Review TypeScript setup. Decide whether to keep extending .nuxt/tsconfig.json or use project references; if adopting references, align type augmentations and CI checks with each context.
  6. Verify modules and application checks. Nuxt warns that some modules may need updates. Run the project’s build, type-check, and relevant tests after addressing migration issues.

The upgrade decision is therefore less about whether app/ is mandatory—it is not—and more about whether the project’s modules, shared fetch state, nested data behavior, and TypeScript setup are ready for Nuxt 4’s changed defaults.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.