Nuxt: The Vue Full-Stack Framework
Nuxt is the open-source full-stack framework for Vue: file-based routing, SSR, static generation and the Nitro server. How it works and what Nuxt 4 is.
What is Nuxt?
Nuxt is the open-source full-stack framework built on Vue.js. Vue is the UI library; Nuxt adds what a production app needs around it: file-based routing, server-side rendering, static generation, server API endpoints, build tooling and deployment. It plays the same role for Vue that Next.js plays for React and SvelteKit for Svelte.
Nuxt 4 is the current stable major version: it was released on 15 July 2025. It is built on Vue 3, Vite and the Nitro server engine, and keeps application code in an app/ directory by default. Nitro can output a Node.js server or a build for several hosting platforms, selected with a preset.
How Nuxt works
A request reaches a Nitro server. For a page, Nuxt renders the Vue component to HTML on the server (server-side rendering), sends it, and the browser then hydrates it into an interactive app. The same project can also pre-render routes at build time (static site generation) or run as a client-only single page app, and you can mix these per route.
Project structure
my-app/
├── app/
│ ├── pages/ # file-based routing
│ │ ├── index.vue # /
│ │ └── blog/[slug].vue # /blog/:slug
│ ├── components/ # auto-imported
│ ├── composables/ # auto-imported
│ ├── layouts/default.vue
│ └── app.vue
├── server/
│ └── api/posts.get.ts # GET /api/posts
├── public/
└── nuxt.config.ts
Routing and data fetching
Every .vue file in pages/ becomes a route; [slug] makes a dynamic parameter. Data loading uses composables that work on both server and client:
<script setup lang="ts">
const route = useRoute();
const { data: post } = await useFetch(`/api/posts/${route.params.slug}`);
</script>| Composable | Use case |
|---|---|
useFetch | Fetch a URL during render, with SSR and caching handled for you |
useAsyncData | Wrap any async function with the same caching |
$fetch | Plain HTTP call, no render integration; use for events and actions |
useState | SSR-safe shared state |
Server API routes
Files under server/api/ become endpoints, and the HTTP method comes from the file name (posts.get.ts, posts.post.ts, [id].delete.ts). You do not need a separate Express server for a typical backend.
// server/api/posts/[slug].get.ts
export default defineEventHandler(async (event) => {
const slug = getRouterParam(event, 'slug');
const post = await db.post.findUnique({ where: { slug } });
if (!post) throw createError({ statusCode: 404, message: 'Not found' });
return post;
});
Rendering modes
Nuxt renders on the server by default (universal rendering). Set ssr: false for client-only rendering, or choose per route with routeRules. For a fully static site run nuxt generate.
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // built once, served static
'/dashboard/**': { ssr: false }, // client-side only
'/blog/**': { isr: 60 } // ISR: CDN-cached where the host supports it
}
});
Nuxt vs Next.js vs SvelteKit
| Nuxt | Next.js | SvelteKit | |
|---|---|---|---|
| Based on | Vue 3 | React | Svelte |
| Server engine | Nitro | Next.js runtime | Adapters |
| Auto-imports | Yes, by default | No | No |
| File-based routing | Yes | Yes | Yes |
All three cover the same ground, so the real choice is the UI library your team already knows.
Common mistakes
- Fetching with
$fetchduring render. The server fetches, the client fetches again and the page flickers or double-loads. UseuseFetchoruseAsyncDatafor render-time data. - Using browser-only APIs on the server.
windowandlocalStoragedo not exist during SSR; guard them or run them inonMounted. - Hydration mismatches. Random values, dates or locale-dependent output that differ between server and client produce warnings and extra work.
- Uncached SSR on hot pages. Rendering on every request is CPU work. Cache with
routeRules(swr,isr) or prerender what does not change.
Load testing a Nuxt app
SSR moves rendering onto your server, so traffic costs CPU there, not only bandwidth. Test the rendered pages and the /api routes separately, with a ramp that matches real traffic, and watch response time percentiles rather than averages. LoadFocus load testing runs JMeter and k6 scripts from 25+ cloud regions; for the client-heavy side see load testing single page applications.
FAQ: Nuxt
Should I use Nuxt 4 or Nuxt 3?
Start new projects on Nuxt 4, stable since 15 July 2025. Existing Nuxt 3 apps can migrate step by step; the main changes are the app/ directory layout and data-fetching behavior, and the official upgrade guide covers both.
Nuxt or plain Vue?
Plain Vue fits a single page app you control end to end. Choose Nuxt when you need server rendering, static generation, SEO-critical pages or ready-made conventions.
Can Nuxt run on Cloudflare Workers?
Yes. Nitro has Cloudflare presets (cloudflare_module for Workers, cloudflare_pages for Pages), set with nitro.preset or the NITRO_PRESET variable at build time.
Can I build a static site with Nuxt?
Yes. Run nuxt generate to pre-render routes into static files.
What is the difference between useFetch and $fetch?
useFetch integrates with rendering: it fetches once on the server, passes the result to the client and caches it. $fetch is a plain call without that handling.
Does Nuxt support TypeScript?
Yes, with generated types for routes and server APIs.
Related terms
Related LoadFocus Tools
Put this concept into practice with LoadFocus, the same platform that powers everything you just read about.