Skip to main content

Command Palette

Search for a command to run...

Vue To Nuxt: Part 2

Setting Up Your First Nuxt 4 Project

Updated

Previously in part 1, we covered what Nuxt is and why it’s worth learning: file-based routing, built-in SEO, SSR support, and consistent project structure. Now it’s time to get hands-on. This article walks you through creating a fresh Nuxt 4 project, exploring what the scaffolder generates, and running your dev server for the first time.

Why Setup Matters

Before jumping into code, In plain Vue with Vite, you’re already juggling three things (Vue, Vue Router, and build config) before writing a single component. Nuxt’s create-nuxt command handles all that in seconds—and teaches you the conventions while doing it.

The folder structure generated by Nuxt isn’t random. It mirrors how Nuxt thinks about your app: where routes live, where server code goes, and how plugins are structured. Understanding this structure now saves hours of confusion later.

Prerequisites: Check Your Node.js Version

Nuxt 4 requires Node.js 18.x or higher. Older versions will cause errors during installation.

Check your version:

node --version

If you’re below 18, visit nodejs.org and upgrade. Use the LTS version (currently 20.x or 22.x) for stability.

Creating a Nuxt 4 Project

Open your terminal and run:

npm create nuxt@latest my-nuxt-app

Replace my-nuxt-app with your project name.

The scaffolder will prompt you with a few questions:

✓ Which package manager would you like to use? npm / yarn / pnpm / bun
✓ Initialize git repository? yes / no
✓ Install dependencies? yes / no

For your first project, stick with npm, yes for Git, and yes for installing dependencies.

After installation finishes, navigate into your project:

cd my-nuxt-app

You should now see your project folder. Let’s explore what’s inside.

Understanding the Nuxt 4 Folder Structure

This is one of the most significant changes in Nuxt 4: the new directory layout. Files are now organized more logically than in Nuxt 3.

Here’s what a fresh Nuxt 4 project looks like:

my-nuxt-app/
├── app/                  # All frontend code lives here
│   ├── app.vue          # Root component (like App.vue in Vue)
│   ├── error.vue        # Error boundary component
│   ├── components/      # Reusable components (auto-imported)
│   ├── layouts/         # Page layouts (auto-imported)
│   ├── pages/           # File-based routes
│   ├── plugins/         # Initialize plugins
│   ├── middleware/      # Route guards & middleware
│   └── assets/          # Images, fonts, stylesheets
├── server/              # Backend code
│   ├── api/             # API routes (auto-exposed as endpoints)
│   ├── middleware/      # Server middleware
│   └── utils/           # Server utilities
├── public/              # Static files (served as-is)
├── nuxt.config.ts       # Nuxt configuration
├── package.json         # Dependencies & scripts
├── .gitignore          # Git ignore rules
└── tsconfig.json       # TypeScript config (if using TS)

Each folder has a purpose:

app/ — This is new in Nuxt 4. The single-tier app folder replaces the scattered layout of Nuxt 3. It clearly separates frontend code from server code.

app.vue — Your root component. Every page is rendered inside this component. Think of it as the main App.vue from Vue projects.

pages/ — File-based routing. Drop a .vue file here, and Nuxt automatically creates a route. More on this in Part 3.

components/ — Reusable UI components. Components here are auto-imported. No import Button from '@/components/Button' needed.

layouts/ — Shared page templates. If multiple pages share the same header and footer, use a layout. Also auto-imported.

server/api/ — Backend routes. A file like server/api/hello.ts becomes an endpoint at /api/hello.

public/ — Static assets served directly. Favicons, robots.txt, pre-optimized images go here.

nuxt.config.ts — Central configuration. Rendering mode, modules, build settings—all here.

Whyapp/ nested now? Performance. Nuxt's dev server boots faster because it doesn't scan unrelated server files when bundling frontend code.

Starting the Dev Server

Everything is ready now. Start the development server:

npm run dev

Exploring the Generated Files

Let’s look at a few key files to understand Nuxt better.

app.vue

<template>
  <div>
    <NuxtWelcome />
  </div>
</template>

Similar to Vue, this is the root component. Everything rendered on your site flows through here. The <NuxtWelcome /> component is just a placeholder—you'll replace it with your layout and pages shortly.

nuxt.config.ts

export default defineNuxtConfig({
  compatibilityDate: '2025-11-30',
})

This is your Nuxt configuration file. It’s minimal by default, but you’ll add options here later:

  • Rendering mode (SSR, SSG, SPA)

  • Modules (if using UI libraries, API clients, etc.)

  • Build settings (compression, optimization)

  • Environment variables (API URLs, secrets)

For now, the default config works fine.

package.json

{
  "name": "my-nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "dependencies": {
    "nuxt": "^4.0.0",
    "vue": "^3.4.0"
  }
}

Important Differences from Nuxt 3

  1. The app/ folder is now mandatory
    In Nuxt 3, you could scatter components, layouts, and pages in the project root. Nuxt 4 groups all frontend code inside app/. This improves clarity and dev server performance.

  2. Directory structure is stricter
    Nuxt 3 allowed customization (e.g., renaming the components folder). Nuxt 4 enforces standard conventions more strictly. This is by design—less flexibility means less confusion.

  3. Smaller default config
    Nuxt 4 removes several config options that were redundant or unused. The config file is leaner and easier to read.

Common First-Time Pitfalls

Pitfall 1

**Trying to create pages before understanding file-based routing:
**New users often create an index.vue file inside pages/ and then wonder why it's not showing up. Remember: in Nuxt, file paths directly map to routes. pages/index.vue = /, pages/about.vue = /about, pages/blog/[id].vue = /blog/:id. More on this in Part 3.

Pitfall 2

Adding components directly to app.vue instead of using the pages/ folder:app.vue is the wrapper. Real content goes in pages. app.vue should contain a layout structure (header, nav, footer) and a <NuxtPage /> component where pages render. Don't jam everything into app.vue.

Pitfall 3

Forgetting that files in the server/ **folder are backend code:**The server/ directory runs on Node.js, not in the browser. You can't use browser APIs here (like document, window, localStorage). This separation is intentional—it keeps concerns clean and security tight.

Pitfall 4

Ignoring nuxt.config.ts **early on:**Some developers treat the config file as “advanced setup” and avoid it. Don’t. You’ll need it soon for SSR settings, module setup, or environment variables. Bookmark it and check it regularly.

Summary: What’s Next

  • Node.js 18+ is required; check your version before starting.

  • Use npm create nuxt@latest to bootstrap a new Nuxt project.

  • Nuxt 4’s key change: the app/ folder groups all frontend code, separating it from backend (server/).

  • Your dev server runs at http://localhost:3000/ by default and supports hot reload via Vite.

  • Files in pages/, components/, and layouts/ are auto-imported—no manual imports needed.

  • nuxt.config.ts is your central config hub; you'll return to it frequently.

Next article: Part 3 covers file-based routing and dynamic routes—how Nuxt turns folder structure into your app’s navigation.