Getting Started with Nuxt.js
If you’re a Vue developer looking to build production-ready applications with a modern workflow, Nuxt 4 gives you the fastest path forward. Nuxt builds on Vue 3 with server-side rendering, hybrid rendering, file-based routing, and a unified deployment model that works across Node, static hosts, serverless, and edge environments.
This beginner-friendly tutorial walks you through creating your first Nuxt 4 application using current defaults like Vue 3, Vite, TypeScript, composables, and Nitro.
Key Takeaways
- Nuxt 4 extends Vue 3 with SSR, hybrid rendering, automatic routing, and built-in optimizations
- File-based routing, composables, and auto-imports reduce configuration and boilerplate
- TypeScript is fully integrated with automatic type generation
- Deploy anywhere using Nitro’s platform-agnostic build output
What Is Nuxt 4 and Why Should You Use It?
Nuxt 4 is the current major release of the Nuxt framework and the recommended choice for new Vue applications in late 2025. It uses Vue 3, Vite, and the Nitro server engine to deliver a fast development experience and a flexible production architecture.
Unlike plain Vue apps, Nuxt 4 provides SSR out of the box, manages routing automatically, handles data fetching in both server and client contexts, and ships with a predictable, convention-driven project structure.
Vue 3 + Vite by Default
Nuxt 4 uses Vite for its dev server and build pipeline. This gives you near-instant hot module replacement, fast cold starts, and highly optimized output bundles.
The Vue 3 Composition API and TypeScript-first design provide strong type inference, better code organization, and predictable component behavior.
TypeScript, No Setup Required
TypeScript support is built in. Nuxt automatically generates types based on your project directories, API routes, middleware, and components. Your IDE understands your entire project from the moment you hit save.
Setting Up Your First Nuxt 4 Project
Installation with npm create nuxt@latest
Scaffold a new project using the modern Nuxt 4 CLI:
npm create nuxt@latest my-app
cd my-app
npm install
npm run dev
This sets up a Nuxt 4 project with TypeScript, Vite, Nitro, and auto-imported composables ready to go.
Directory Structure Overview
A fresh Nuxt 4 project includes:
pages/— File-based routingcomponents/— Auto-imported componentscomposables/— Reusable logic with automatic importsserver/api/— Server endpoints powered by Nitropublic/— Static assetsnuxt.config.ts— TypeScript-first configuration
This structure eliminates setup overhead and keeps everything predictable.
Core Concepts: Pages, Layouts, Composables, Auto-Imports
File-Based Routing in Nuxt 4
Add a Vue file inside pages/ and Nuxt automatically creates a route:
<!-- pages/products/[id].vue -->
<script setup lang="ts">
const route = useRoute()
const id = route.params.id
</script>
<template>
<h1>Product {{ id }}</h1>
</template>
Dynamic route parameters use square brackets.
Layouts for Shared UI
Layouts allow shared wrappers around pages:
<!-- layouts/default.vue -->
<template>
<AppHeader />
<main><slot /></main>
<AppFooter />
</template>
Pages use the default layout automatically. You can switch layouts using definePageMeta.
Composables and Auto-Imports
Composables inside composables/ are auto-imported everywhere:
// composables/useCounter.ts
export const useCounter = () => {
const count = useState('count', () => 0)
const inc = () => count.value++
return { count, inc }
}
No import statements, no boilerplate — Nuxt handles all of it.
Discover how at OpenReplay.com.
Data Fetching in Nuxt 4
useFetch for SSR-Aware Requests
useFetch handles server-side data loading and client hydration:
<script setup lang="ts">
const { data: posts } = await useFetch('/api/posts')
</script>
This avoids double-fetching between server and client and works seamlessly with Nitro.
API Routes via Nitro
Create server endpoints in server/api/:
// server/api/posts.get.ts
export default defineEventHandler(async () => {
const posts = await $fetch('https://jsonplaceholder.typicode.com/posts')
return posts.slice(0, 5)
})
Nitro optimizes these endpoints for Node, static, serverless, or edge deployments automatically.
useAsyncData for Custom Logic
If you need more control:
<script setup lang="ts">
const { data } = await useAsyncData('posts', () =>
$fetch('/api/posts', { query: { limit: 5 } })
)
</script>
State Management with Pinia
For application-level state, Nuxt 4 uses Pinia:
npm install @pinia/nuxt
Enable it:
export default defineNuxtConfig({
modules: ['@pinia/nuxt']
})
Create a store:
// stores/user.ts
export const useUserStore = defineStore('user', () => {
const profile = ref(null)
async function load() {
profile.value = await $fetch('/api/user')
}
return { profile, load }
})
Pinia integrates directly with Nuxt’s auto-imports and SSR behavior.
Rendering Modes in Nuxt 4
Server-Side Rendering by Default
Nuxt 4 renders pages on the server for SEO and performance. You can adjust rendering per route:
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
'/admin/**': { ssr: false },
'/blog/**': { isr: 3600 }
}
})
This enables hybrid apps that mix SSR, prerendered static pages, and dynamic client-only sections.
Static Generation and Hybrid Deployment
Generate static output if needed:
npm run generate
You can prerender marketing pages, keep dashboards dynamic, and run everything through Nitro.
Deploying Your Nuxt 4 Application
Build for Production
npm run build
Nuxt outputs a .output/ directory containing server code, client assets, and presets for every major hosting platform.
Platform-Agnostic Deployment
Deploy to:
- Node servers
- Static hosts
- Serverless platforms (AWS, Vercel, Netlify)
- Edge networks (Cloudflare Workers, Vercel Edge)
Nitro selects the right preset automatically.
Conclusion
Getting started with Nuxt.js today means using Nuxt 4.
With SSR by default, hybrid rendering, auto-imports, composables, and Nitro powering deployment, Nuxt 4 gives you everything you need to build fast, modern, maintainable Vue applications.
Start with:
npm create nuxt@latest
—and you’re already on the right foundation.
FAQs
useFetch is a convenience wrapper for HTTP-centric requests with SSR hydration. useAsyncData is a lower-level primitive for custom data-loading logic. Both work seamlessly with Nitro.
Yes. Set ssr: false in nuxt.config.ts for SPA behavior, or configure SSR per-route using routeRules.
Nuxt 4 provides built-in type generation for routes, API handlers, components, composables, and server utilities with no manual setup required.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.