Next.js course Β· Module 1: Next.js Configuration

Project Initialization and Available Starters

10 min read
In this lesson10

In Quantum Metropolis, engineers often use predefined quantum schematics to accelerate the development of new city systems. Similarly, in the Next.js world, we can use various starter templates and configurations that allow us to start working on a new application more quickly. In this module, we will explore the available starters for Next.js 16 and learn how to effectively initialize new projects.

Basic Project Initialization

As we already know from the previous lesson, the simplest way to start a new Next.js project is to use the create-next-app tool:

1npx create-next-app@latest my-quantum-project

This command creates a new Next.js project with default configuration. It is like launching a basic residential module in Quantum Metropolis - functional, but you may want to customize it to your specific needs.

Configuration Options for create-next-app

When creating a new project, create-next-app first asks whether you want the recommended defaults (TypeScript, ESLint, Tailwind CSS, App Router and AGENTS.md). If you choose your own settings, you will see further questions. Let's take a closer look at them:

1Would you like to use the recommended Next.js defaults? No, customize settings
2Would you like to use TypeScript? Yes
3Which linter would you like to use? ESLint
4Would you like to use React Compiler? No
5Would you like to use Tailwind CSS? Yes
6Would you like your code inside a `src/` directory? Yes
7Would you like to use App Router? (recommended) Yes
8Would you like to customize the import alias (`@/*` by default)? No
9Would you like to include AGENTS.md to guide coding agents to write up-to-date Next.js code? Yes

TypeScript

TypeScript adds static typing to JavaScript, helping catch errors while writing code. In Quantum Metropolis, this would be similar to early warning systems that detect problems before they become critical.

1// JavaScript
2function addEnergy(reactor, amount) {
3  return reactor.level + amount;
4}
5
6// TypeScript
7interface Reactor {
8  level: number;
9  maxCapacity: number;
10  status: 'active' | 'inactive' | 'maintenance';
11}
12
13function addEnergy(reactor: Reactor, amount: number): number {
14  if (reactor.status !== 'active') {
15    throw new Error('Reactor must be active to add energy');
16  }
17  return reactor.level + amount;
18}

ESLint

ESLint is a static code analysis tool that helps maintain consistent style and detect potential issues. It is like an automatic quality controller in Quantum Metropolis factories. In Next.js 16 the wizard also lets you pick Biome instead, a fast linter and formatter in one tool, or skip the linter entirely.

React Compiler

React Compiler memoizes components automatically, so you reach for useMemo and useCallback by hand less often. In Next.js 16 its support is stable but switched off by default, because it makes compilation slower; to start with, you can answer "No".

Tailwind CSS

Tailwind CSS is a CSS framework based on utility classes. Instead of writing your own CSS styles, you use predefined classes directly in HTML. It is like the modular construction system in Quantum Metropolis - instead of designing each building from scratch, engineers combine ready-made modules.

1// Without Tailwind
2<button className="login-button">Log in</button>
3
4// With Tailwind
5<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
6  Log in
7</button>

The src/ Directory

Using the src/ directory is a good organizational practice that separates source code from configuration files. It is like separating the management center from the infrastructure in Quantum Metropolis.

App Router

The App Router is a modern routing approach in Next.js, based on React Server Components. It is a key feature of Next.js 16, which we definitely recommend using in new projects.

Import Alias @/*

The import alias @/* allows you to use a shorthand path for importing modules from the src/ directory (from the project root in a project without src/). It is like the rapid transit system in Quantum Metropolis - a shortcut that saves time.

1// Without alias
2import { Button } from '../../../components/ui/Button';
3
4// With alias @/*
5import { Button } from '@/components/ui/Button';

AGENTS.md

The last question is about an AGENTS.md file with instructions for AI coding agents such as Claude or Cursor. The file points them to the documentation bundled with your installed Next.js version, so the code they suggest fits your project rather than older versions of the framework.

Official Starter Templates

Next.js offers several official starter templates that you can use as the foundation for your project. To use them, use the --example flag:

1npx create-next-app@latest my-quantum-blog --example blog-starter

Here are some of the most popular official templates:

1. Tailwind CSS without a template

The separate with-tailwindcss example is no longer in the Next.js repository: create-next-app installs Tailwind CSS itself (in the recommended defaults or with the --tailwind flag).

1npx create-next-app@latest my-tailwind-app --tailwind

2. with-typescript

A template with TypeScript already configured.

1npx create-next-app@latest --example with-typescript my-ts-app

3. blog-starter

A Markdown blog template, ready to use.

1npx create-next-app@latest --example blog-starter my-blog

4. Next.js Commerce

A full e-commerce store built on the App Router, maintained in its own repository, vercel/commerce.

1npx create-next-app@latest --example https://github.com/vercel/commerce my-store

Next.js Templates - Advanced Starters

Vercel, the company behind Next.js, also offers more advanced templates at vercel.com/templates. These are ready-made projects for specific use cases. This resembles how Quantum Metropolis architects can choose ready-made plans for different types of city structures.

Some noteworthy templates:

Chatbot (formerly Next.js AI Chatbot)

An AI chatbot similar to ChatGPT, built with Next.js and the AI SDK; it connects models (e.g. OpenAI, Anthropic, Google, xAI) through the Vercel AI Gateway.

1npx create-next-app@latest ai-chatbot \
2  --use-pnpm \
3  --example "https://github.com/vercel/chatbot"

Next.js + Supabase

A Next.js starter with Supabase: sign-in with Supabase Auth using cookie-based sessions, Tailwind CSS and shadcn/ui components.

1npx create-next-app@latest supabase-app \
2  --use-pnpm \
3  --example "https://github.com/vercel/next.js/tree/canary/examples/with-supabase"

Community Starters

In addition to official templates, the Next.js community has created many of their own starters. These are like experimental architectural projects in Quantum Metropolis - not part of the official infrastructure, but they can offer innovative solutions.

T3 Stack

T3 Stack is a popular toolkit for building Next.js applications with TypeScript, tRPC, Tailwind CSS, and Prisma.

1npm create t3-app@latest

Next.js Nextra

Nextra is a framework for creating static sites and documentation based on Next.js.

1npx create-next-app@latest my-docs-site \
2  --use-pnpm \
3  --example "https://github.com/shuding/nextra-docs-template"

Project Structure After Initialization

After initializing a Next.js 16 project with App Router, you will see the following file structure:

1my-quantum-project/
2β”œβ”€β”€ src/                 # Application source code
3β”‚   └── app/             # App Router directory
4β”‚       β”œβ”€β”€ favicon.ico  # Page icon
5β”‚       β”œβ”€β”€ globals.css  # Global CSS styles
6β”‚       β”œβ”€β”€ layout.tsx   # Main application layout
7β”‚       └── page.tsx     # Home page
8β”œβ”€β”€ public/              # Static files
9β”‚   └── next.svg         # Next.js logo
10β”œβ”€β”€ AGENTS.md            # Guidance for AI coding agents
11β”œβ”€β”€ CLAUDE.md            # Points to AGENTS.md
12β”œβ”€β”€ eslint.config.mjs    # ESLint configuration
13β”œβ”€β”€ next.config.ts       # Next.js configuration
14β”œβ”€β”€ package.json         # Dependencies and scripts
15β”œβ”€β”€ postcss.config.mjs   # PostCSS configuration (Tailwind CSS 4)
16└── tsconfig.json        # TypeScript configuration

Let's take a closer look at some of these files:

src/app/page.tsx

This is the main page of your application, accessible at /.

1export default function Home() {
2  return (
3    <main className="flex min-h-screen flex-col items-center justify-between p-24">
4      <h1 className="text-4xl font-bold">Welcome to Quantum Metropolis</h1>
5      <p className="text-xl">The future starts here.</p>
6    </main>
7  );
8}

src/app/layout.tsx

This file defines the layout that will be shared across all pages in your application.

1import './globals.css';
2import type { Metadata } from 'next';
3
4export const metadata: Metadata = {
5  title: 'Quantum Metropolis',
6  description: 'Management portal for the city of the future systems',
7};
8
9export default function RootLayout({
10  children,
11}: {
12  children: React.ReactNode;
13}) {
14  return (
15    <html lang="en">
16      <body>{children}</body>
17    </html>
18  );
19}

next.config.ts

This file contains the Next.js configuration; create-next-app creates it in TypeScript right away. You can extend it with your own settings, for example a list of servers that images may be loaded from:

1import type { NextConfig } from 'next';
2
3const nextConfig: NextConfig = {
4  // Your configurations
5  images: {
6    remotePatterns: [
7      { protocol: 'https', hostname: 'quantum-metropolis.example.com' },
8    ],
9  },
10};
11
12export default nextConfig;

The remotePatterns option replaced the old images.domains, which is deprecated in Next.js 16. Patterns let you specify the protocol and server address precisely, which makes them safer.

Modifying an Existing Project

After initializing a project, you will usually want to customize it to your needs. Here are some typical changes:

1. Updating Metadata

Update the src/app/layout.tsx file to change the application title and description:

1export const metadata: Metadata = {
2  title: 'Quantum Metropolis Management System',
3  description: 'Advanced interface for monitoring and controlling city systems',
4};

2. Adding Dependencies

Install additional libraries you need:

1npm install axios @tanstack/react-query zustand

3. Configuring Folder Structure

Create folders for typical application elements:

1mkdir -p src/components/ui
2mkdir -p src/lib
3mkdir -p src/hooks
4mkdir -p src/utils

4. Customizing Styles

If you are using Tailwind CSS 4, which create-next-app installs, you customize the theme directly in the globals.css file with the @theme directive:

1/* src/app/globals.css */
2@import "tailwindcss";
3
4@theme {
5  --color-quantum-primary: #3B82F6;
6  --color-quantum-secondary: #10B981;
7  --color-quantum-accent: #8B5CF6;
8  --color-quantum-dark: #1F2937;
9  --font-sans: "Inter", sans-serif;
10  --font-mono: "Fira Code", monospace;
11}

Every variable prefixed with --color- creates new classes, for example bg-quantum-primary or text-quantum-accent, and --font-sans changes the typeface used by the font-sans class. In the older Tailwind CSS 3, the same settings went into a tailwind.config.ts file, which you will still find in many existing projects:

1import type { Config } from 'tailwindcss';
2
3const config: Config = {
4  content: [
5    './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
6    './src/components/**/*.{js,ts,jsx,tsx,mdx}',
7    './src/app/**/*.{js,ts,jsx,tsx,mdx}',
8  ],
9  theme: {
10    extend: {
11      colors: {
12        quantum: {
13          primary: '#3B82F6',
14          secondary: '#10B981',
15          accent: '#8B5CF6',
16          dark: '#1F2937',
17        },
18      },
19      fontFamily: {
20        sans: ['Inter', 'sans-serif'],
21        mono: ['Fira Code', 'monospace'],
22      },
23    },
24  },
25  plugins: [],
26};
27export default config;

In a new Next.js 16 project with Tailwind CSS 4 this file is not needed, so do not create it without a reason.

Git and .gitignore Configuration

When you initialize a project using create-next-app, git will be automatically initialized and a .gitignore file will be created. This is like the plan control and archiving system in Quantum Metropolis - it allows you to track changes and collaborate with other engineers.

create-next-app also makes the first commit ("Initial commit from Create Next App"). Save your own changes with the next one:

1git add .
2git commit -m "Initialize Next.js 16 project"

Customizing npm Scripts

You can customize scripts in the package.json file to simplify frequently performed tasks:

1"scripts": {
2  "dev": "next dev",
3  "build": "next build",
4  "start": "next start",
5  "lint": "eslint",
6  "format": "prettier --write \"**/*.{js,ts,tsx,md}\"",
7  "update-deps": "npm update"
8}

Note the lint script: in Next.js 16 it runs eslint directly, because the old next lint command was removed. The dev and build scripts need no flags, since Turbopack is now the default bundler.

Summary

Initializing a Next.js 16 project and choosing the right starter is the foundation for your application's success, just as solid foundations are key for every building in Quantum Metropolis. In this module, we explored various project initialization options, from basic create-next-app to advanced community templates.

Choosing the right starter depends on your specific needs. For simpler projects, the default create-next-app template may be sufficient. For more complex applications, consider using one of the official templates or community solutions.

Remember that a well-organized project start will save you a lot of time and problems in the future, just as careful planning of city infrastructure in Quantum Metropolis prevents problems with its expansion.

In the next lesson, we will delve into the directory and file structure in Next.js, comparing the new App Router with the traditional Pages Router.

Code for this lesson: App.tsx
1// JSX and Components - Metropolis Quantum
2import React from 'react';
3
4console.log("JSX and Components in React");
5console.log("Building the Quantum City interface\n");
6
7// ==========================================
8// 1. What is JSX?
9// ==========================================
10console.log("=== 1. JSX (JavaScript XML) ===");
11
12// JSX is a JavaScript syntax extension
13// It allows writing HTML-like code in JavaScript
14const quantumTitle = <h1>Metropolis Quantum</h1>;
15
16console.log("JSX element:", quantumTitle);
17
18// JSX with JavaScript expressions
19const cityName = "Quantum City";
20const population = 2470000;
21
22const cityInfo = (
23  <div>
24    <h2>Welcome to {cityName}!</h2>
25    <p>Population: {population.toLocaleString()} residents</p>
26    <p>Status: {population > 2000000 ? "Megapolis" : "City"}</p>
27  </div>
28);
29
30// ==========================================
31// 2. Functional Components
32// ==========================================
33console.log("\n=== 2. Functional Components ===");
34
35// Simple component
36function WelcomeMessage() {
37  return (
38    <div style={{
39      background: 'linear-gradient(45deg, #7c4dff, #64ffda)',
40      padding: '20px',
41      borderRadius: '10px',
42      color: 'white',
43      textAlign: 'center'
44    }}>
45      <h2>Welcome to the Future!</h2>
46      <p>Metropolis Quantum - City of Technology</p>
47    </div>
48  );
49}
50
51// Component with props
52interface BuildingCardProps {
53  name: string;
54  height: number;
55  type: 'residential' | 'commercial' | 'industrial';
56  lights: boolean;
57}
58
59const BuildingCard: React.FC<BuildingCardProps> = ({ name, height, type, lights }) => {
60  const getTypeIcon = () => {
61    switch(type) {
62      case 'residential': return '●';
63      case 'commercial': return 'β– ';
64      case 'industrial': return 'β–²';
65      default: return 'β–‘';
66    }
67  };
68
69  const getTypeColor = () => {
70    switch(type) {
71      case 'residential': return '#4caf50';
72      case 'commercial': return '#2196f3';
73      case 'industrial': return '#ff9800';
74      default: return '#9e9e9e';
75    }
76  };
77
78  return (
79    <div style={{
80      background: 'rgba(255, 255, 255, 0.1)',
81      padding: '15px',
82      borderRadius: '8px',
83      border: `2px solid ${getTypeColor()}`,
84      marginBottom: '10px'
85    }}>
86      <h3 style={{ color: getTypeColor() }}>
87        {getTypeIcon()} {name}
88      </h3>
89      <p>Height: {height}m</p>
90      <p>Type: {type}</p>
91      <p>Lights status: {lights ? 'On' : 'Off'}</p>
92    </div>
93  );
94};
95
96// ==========================================
97// 3. Component Composition
98// ==========================================
99console.log("\n=== 3. Component Composition ===");
100
101function CityDashboard() {
102  const buildings = [
103    { id: 1, name: 'Quantum Tower', height: 850, type: 'commercial' as const, lights: true },
104    { id: 2, name: 'Neural Apartments', height: 450, type: 'residential' as const, lights: true },
105    { id: 3, name: 'Cyber Factory', height: 320, type: 'industrial' as const, lights: false }
106  ];
107
108  return (
109    <div style={{
110      padding: '20px',
111      background: 'linear-gradient(135deg, #0f0f23 0%, #1a1a2e 100%)',
112      minHeight: '100vh',
113      color: 'white'
114    }}>
115      <WelcomeMessage />
116
117      <div style={{ marginTop: '30px' }}>
118        <h2 style={{ color: '#64ffda' }}>Metropolis Buildings</h2>
119        {buildings.map(building => (
120          <BuildingCard
121            key={building.id}
122            name={building.name}
123            height={building.height}
124            type={building.type}
125            lights={building.lights}
126          />
127        ))}
128      </div>
129
130      <div style={{
131        marginTop: '30px',
132        background: 'rgba(124, 77, 255, 0.2)',
133        padding: '15px',
134        borderRadius: '8px',
135        borderLeft: '4px solid #7c4dff'
136      }}>
137        <h3>JSX Tips:</h3>
138        <ul style={{ lineHeight: '1.8' }}>
139          <li>JSX is not a string, not HTML - it's JavaScript!</li>
140          <li>Use {} for JavaScript expressions</li>
141          <li>className instead of class (JS keyword)</li>
142          <li>camelCase for attributes (onClick, onChange)</li>
143          <li>Every element must be closed</li>
144        </ul>
145      </div>
146    </div>
147  );
148}
149
150// Render application
151function App() {
152  console.log("Rendering CityDashboard...");
153  return <CityDashboard />;
154}
155
156export default App;

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. Server-Side Rendering (SSR) in Next.js means:

  2. 2. Static Site Generation (SSG) in Next.js is:

Hands-on tasks in the game

  • Vertical ordering

    Arrange the steps to launch a new Next.js project

  • Click in order

    Arrange the syntax for importing the React library

Useful articles