---
title: "Create Next App"
description: "Create Next App is the official command-line bootstrapping tool designed to set up new Next.js applications quickly and reliably. It automates the entire project initialization lifecycle, eliminati..."
last_updated: "2026-09-23T10:52:03.135025+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/ecosystem-packages/create-next-app"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/create-next-app/index.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/index.ts)
- [packages/create-next-app/templates/index.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/index.ts)
- [packages/create-next-app/create-app.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts)
- [packages/next/src/bin/next.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/bin/next.ts)
- [packages/next-codemod/transforms/cra-to-next.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/transforms/cra-to-next.ts)
- [packages/next/src/cli/next-info.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/next-info.ts)
- [packages/next-codemod/bin/upgrade.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/upgrade.ts)
- [packages/next/src/cli/next-dev.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/next-dev.ts)
- [packages/create-next-app/package.json](https://github.com/blade47/next.js/blob/main/packages/create-next-app/package.json)
- [run-evals.js](https://github.com/blade47/next.js/blob/main/run-evals.js)
- [packages/next-codemod/bin/agents-md.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/agents-md.ts)
- [packages/create-next-app/helpers/examples.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts)
- [packages/create-next-app/templates/default-tw/js/pages/index.js](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default-tw/js/pages/index.js)
- [packages/next-codemod/bin/next-codemod.ts](https://github.com/blade47/next.js/blob/main/packages/next-codemod/bin/next-codemod.ts)
- [packages/next/src/cli/next-build.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/next-build.ts)
- [packages/create-next-app/templates/default/js/pages/index.js](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default/js/pages/index.js)
- [packages/next/src/cli/next-test.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/next-test.ts)
- [packages/create-next-app/templates/app-tw-empty/ts/next.config.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw-empty/ts/next.config.ts)
- [packages/create-next-app/templates/app-tw/ts/next.config.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw/ts/next.config.ts)
- [packages/create-next-app/templates/app-tw/js/app/page.js](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw/js/app/page.js)
- [packages/create-next-app/tsconfig.json](https://github.com/blade47/next.js/blob/main/packages/create-next-app/tsconfig.json)
- [packages/create-next-app/templates/default-tw/ts/pages/index.tsx](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default-tw/ts/pages/index.tsx)
- [packages/create-next-app/templates/app-empty/ts/next.config.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-empty/ts/next.config.ts)
- [packages/create-next-app/helpers/get-pkg-manager.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/get-pkg-manager.ts)
- [packages/create-next-app/helpers/install.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/install.ts)
</details>

## Overview

Create Next App is the official command-line bootstrapping tool designed to set up new Next.js applications quickly and reliably. It automates the entire project initialization lifecycle, eliminating manual configuration overhead by providing interactive prompts, resolving package dependencies, and scaffolding complete directory structures tailored for either the App Router or Pages Router.

Sources: [packages/create-next-app/package.json:9-9](https://github.com/blade47/next.js/blob/main/packages/create-next-app/package.json#L9-L9), [packages/create-next-app/index.ts:41-123](https://github.com/blade47/next.js/blob/main/packages/create-next-app/index.ts#L41-L123), [packages/create-next-app/create-app.ts:28-264](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L28-L264)

## CLI Entry and Interactive Prompts

### Overview

The `create-next-app` executable initializes as a Node.js CLI tool via `#!/usr/bin/env node`, parsing arguments with `commander` and managing persistent user preferences through `conf`. The CLI entry point configures the command-line interface, handles terminal signals (`SIGINT` and `SIGTERM`), and detects the executing package manager from environment variables or explicit flags.

Sources: [packages/create-next-app/index.ts:1-26](https://github.com/blade47/next.js/blob/main/packages/create-next-app/index.ts#L1-L26), [packages/create-next-app/package.json:1-19](https://github.com/blade47/next.js/blob/main/packages/create-next-app/package.json#L1-L19)

### CLI Command Options

The CLI parses positional directory arguments and options using `commander`. When options are passed, they determine project behavior such as template selection, package manager overrides, and installation flags.

| Option Flag | Description / Default |
| :--- | :--- |
| `-v, --version` | Output the current version of create-next-app. |
| `-h, --help` | Display help message. |
| `--ts, --typescript` | Initialize as a TypeScript project. (default) |
| `--js, --javascript` | Initialize as a JavaScript project. |
| `--tailwind` | Initialize with Tailwind CSS config. (default) |
| `--react-compiler` | Initialize with React Compiler enabled. |
| `--eslint` | Initialize with ESLint config. |
| `--biome` | Initialize with Biome config. |
| `--app` | Initialize as an App Router project. |
| `--src-dir` | Initialize inside a `src/` directory. |
| `--rspack` | Enable Rspack as the bundler. |
| `--import-alias refix/*>` | Specify import alias to use (default `@/*`). |
| `--api` | Initialize a headless API using the App Router. |
| `--empty` | Initialize an empty project. |
| `--use-npm` | Explicitly bootstrap using npm. |
| `--use-pnpm` | Explicitly bootstrap using pnpm. |
| `--use-yarn` | Explicitly bootstrap using Yarn. |
| `--use-bun` | Explicitly bootstrap using Bun. |
| `--reset, --reset-preferences` | Reset saved preferences for create-next-app. |
| `--skip-install` | Explicitly skip installing packages. |
| `--yes` | Use saved preferences or defaults for unprovided options. |
| `-e, --example <example-name\|github-url>` | Bootstrap with an official example or public GitHub URL. |
| `--example-path ath-to-example>` | Specify path to example when URL contains a slash in branch name. |
| `--agents-md` | Include AGENTS.md to guide coding agents. (default) |
| `--disable-git` | Skip initializing a git repository. |

Sources: [packages/create-next-app/index.ts:41-113](https://github.com/blade47/next.js/blob/main/packages/create-next-app/index.ts#L41-L113)

### Package Manager Detection and Execution Flow

The CLI determines which package manager invoked the process by inspecting `process.env.npm_config_user_agent`. The resolution follows a strict evaluation order across explicit flags and environment strings.

```mermaid
flowchart TD
    A[Start: Parse CLI Options] --> B{Explicit flag used?}
    B -->|--use-npm| C[npm]
    B -->|--use-pnpm| D[pnpm]
    B -->|--use-yarn| E[yarn]
    B -->|--use-bun| F[bun]
    B -->|None| G["getPkgManager()"]
    G --> H{npm_config_user_agent starts with?}
    H -->|yarn| E
    H -->|pnpm| D
    H -->|bun| F
    H -->|Other / Empty| C
```

Sources: [packages/create-next-app/index.ts:128-137](https://github.com/blade47/next.js/blob/main/packages/create-next-app/index.ts#L128-L137), [packages/create-next-app/helpers/get-pkg-manager.ts:5-21](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/get-pkg-manager.ts#L5-L21)

The package manager call-chain executes as follows: `getPkgManager()` inspects `process.env.npm_config_user_agent`, checking string prefixes for `yarn`, `pnpm`, or `bun`, and falls back to `npm`. When version inspection is required, `getPackageManagerVersion(packageManager)` checks `userAgentMatch` via regex `new RegExp(`${packageManager}/([\\d.]+[\\w.-]*)`)`, falling back to spawning `execSync(`${packageManager} --version`)`. Finally, `getPnpmMajorVersion()` calls `getPackageManagerVersion('pnpm')`, splits the version string by periods, and parses the major integer via `parseInt()`.

Sources: [packages/create-next-app/helpers/get-pkg-manager.ts:5-65](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/get-pkg-manager.ts#L5-L65)

> [!CAUTION]
> If a user aborts an interactive prompt (`state.aborted`), the CLI explicitly writes the terminal cursor restoration escape sequence `\x1B[?25h` to `process.stdout` before exiting with status code `1`. Omitting this restoration step leaves the user's terminal cursor permanently hidden.

Sources: [packages/create-next-app/index.ts:27-39](https://github.com/blade47/next.js/blob/main/packages/create-next-app/index.ts#L27-L39)

### Prompts and Configuration Defaults

When interactive prompts run, `onPromptState` catches user abort events. If `--reset-preferences` is supplied, `Conf` clears saved settings and exits. Otherwise, default preferences are initialized with TypeScript enabled (`typescript: true`), linter disabled (`eslint: false`, `linter: 'eslint'`), Tailwind CSS enabled (`tailwind: true`), App Router enabled (`app: true`), `src/` directory disabled (`srcDir: false`), and import alias set to `@/*`.

Sources: [packages/create-next-app/index.ts:138-156](https://github.com/blade47/next.js/blob/main/packages/create-next-app/index.ts#L138-L156), [packages/create-next-app/index.ts:232-243](https://github.com/blade47/next.js/blob/main/packages/create-next-app/index.ts#L232-L243)

## Project Creation and Flow Orchestration

### Overview

Once user inputs, CLI flags, and package manager selections are validated, `createApp` orchestrates the target project creation flow. This includes verifying directory permissions, creating target folders, downloading or scaffolding templates, executing package installations, generating agent configuration files, initializing git repositories, and handling execution errors.

Sources: [packages/create-next-app/create-app.ts:28-272](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L28-L272)

### Call-Chain Execution Walkthrough

The project creation flow follows a strict execution path through its core orchestration functions:

`createApp()` → `isWriteable()` → `mkdirSync()` → `isFolderEmpty()` → `process.chdir()` → `install()` → `generateAgentFiles()` → `tryGitInit()`

1. **`createApp()`**: Receives resolved configuration options including `appPath`, `packageManager`, template choices, and flags.
Sources: [packages/create-next-app/create-app.ts:28-66](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L28-L66)
2. **`isWriteable()`**: Evaluates `dirname(root)` to verify whether the parent directory has write permissions before attempting file creation.
Sources: [packages/create-next-app/create-app.ts:134-144](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L134-L144)
3. **`mkdirSync()`**: Creates the destination folder using `resolve(appPath)` with `{ recursive: true }`.
Sources: [packages/create-next-app/create-app.ts:134-148](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L134-L148)
4. **`isFolderEmpty()`**: Inspects the target directory to confirm it contains no conflicting files; exits process code `1` if non-empty.
Sources: [packages/create-next-app/create-app.ts:149-151](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L149-L151)
5. **`process.chdir()`**: Changes the current working directory to `root`.
Sources: [packages/create-next-app/create-app.ts:160-160](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L160-L160)
6. **`install()`**: Spawns the package manager process via `cross-spawn` when installing dependencies or examples.
Sources: [packages/create-next-app/create-app.ts:223-227](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L223-L227), [packages/create-next-app/helpers/install.ts:11-49](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/install.ts#L11-L49)
7. **`generateAgentFiles()`**: Conditionally runs when `agentsMd` is enabled to emit agent guidance files.
Sources: [packages/create-next-app/create-app.ts:261-263](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L261-L263)
8. **`tryGitInit()`**: Initializes a git repository in `root` unless `disableGit` is explicitly set.
Sources: [packages/create-next-app/create-app.ts:265-271](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L265-L271)

### Installation and Dependency Execution

Dependency installation is managed by `install()`, which handles offline detection and passes explicit environment variables to the package manager spawn process.

```typescript
export async function install(
  packageManager: PackageManager,
  isOnline: boolean
): Promise<void> {
  const args: string[] = ['install']
  if (!isOnline) {
    console.log(
      yellow('You appear to be offline.\nFalling back to the local cache.')
    )
    args.push('--offline')
  }
  return new Promise((resolve, reject) => {
    const child = spawn(packageManager, args, {
      stdio: 'inherit',
      env: {
        ...process.env,
        ADBLOCK: '1',
        NODE_ENV: 'development',
        DISABLE_OPENCOLLECTIVE: '1',
      },
    })
    child.on('close', (code) => {
      if (code !== 0) {
        reject({ command: `${packageManager} ${args.join(' ')}` })
        return
      }
      resolve()
    })
  })
}
```

Sources: [packages/create-next-app/helpers/install.ts:11-50](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/install.ts#L11-L50)

> [!WARNING]
> When `packageManager` is set to `yarn` and the host environment is offline, `createApp` forces `isOnline` to `false` via `getOnline()`, which appends the `--offline` flag to installation arguments and instructs Yarn to fall back to its local cache.

Sources: [packages/create-next-app/create-app.ts:153-154](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L153-L154), [packages/create-next-app/helpers/install.ts:17-23](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/install.ts#L17-L23)

### Orchestration Design Trade-offs

| Design Choice | Benefit | Cost |
| :--- | :--- | :--- |
| **Parent Directory Write Check (`isWriteable`)** | Fails fast before modifying the filesystem if permissions are lacking. | Extra asynchronous disk check prior to folder creation. |
| **Forced `NODE_ENV: 'development'` during install** | Ensures package managers like pnpm do not skip required dev dependencies. | Overrides any production environment variables present in the shell. |
| **Best-effort type generation (`runTypegen`)** | Prevents example setup failures if type generation errors out. | Suppresses critical type generation failures during bootstrapping. |

Sources: [packages/create-next-app/create-app.ts:136-144](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L136-L144), [packages/create-next-app/create-app.ts:229-236](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L229-L236), [packages/create-next-app/helpers/install.ts:33-40](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/install.ts#L33-L40)

## Template Engine and Dependency Resolution

### Template Copying and Renaming

The `installTemplate` function handles copying internal template files into the target project root directory, configuring file exclusions based on user selections for ESLint, Biome, and Tailwind CSS.
Sources: [packages/create-next-app/templates/index.ts:48-95](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/index.ts#L48-L95)

```typescript
  const templatePath = path.join(__dirname, template, mode);
  const copySource = ["**"];
  if (!eslint) copySource.push("!eslint.config.mjs");
  if (!biome) copySource.push("!biome.json");
  if (!tailwind) copySource.push("!postcss.config.mjs");

  await copy(copySource, root, {
    parents: true,
    cwd: templatePath,
    rename(name) {
      switch (name) {
        case "gitignore": {
          return `.${name}`;
        }
        case "README-template.md": {
          return "README.md";
        }
        default: {
          return name;
        }
      }
    },
  });
```
Sources: [packages/create-next-app/templates/index.ts:71-95](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/index.ts#L71-L95)

> [!NOTE]
> `README-template.md` is renamed to `README.md` during the copy operation to bypass limitations with `webpack-asset-relocator-loader` used by ncc.
Sources: [packages/create-next-app/templates/index.ts:85-89](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/index.ts#L85-L89)

### Package Version Resolution and Package Manager Detection

Package managers are identified through the `npm_config_user_agent` environment variable or by invoking `--version` via `execSync`.
Sources: [packages/create-next-app/helpers/get-pkg-manager.ts:1-54](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/get-pkg-manager.ts#L1-L54)

| Helper Function | Return Type | Description |
| :--- | :--- | :--- |
| `getPkgManager()` | `PackageManager` ('npm' \| 'pnpm' \| 'yarn' \| 'bun') | Inspects `npm_config_user_agent` to determine the active package manager, defaulting to 'npm'. |
| `getPackageManagerVersion(packageManager)` | `string \| null` | Extracts the version string from user agent or spawns `ackageManager> --version`. |
| `getPnpmMajorVersion()` | `number \| null` | Parses the major integer version specifically for `pnpm`. |

Sources: [packages/create-next-app/helpers/get-pkg-manager.ts:5-65](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/get-pkg-manager.ts#L5-L65)

During test runs, local workspace tarball paths supplied via `NEXT_TEST_PKG_PATHS` override standard package versions to ensure sibling packages install correctly.
Sources: [packages/create-next-app/templates/index.ts:213-234](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/index.ts#L213-L234)

### Dependency Installation Execution

The `install` function spawns the chosen package manager with explicit environment overrides to ensure reliable execution across different user environments.
Sources: [packages/create-next-app/helpers/install.ts:11-49](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/install.ts#L11-L49)

```typescript
export async function install(
  packageManager: PackageManager,
  isOnline: boolean
): Promise<void> {
  const args: string[] = ['install']
  if (!isOnline) {
    console.log(
      yellow('You appear to be offline.\nFalling back to the local cache.')
    )
    args.push('--offline')
  }
  return new Promise((resolve, reject) => {
    const child = spawn(packageManager, args, {
      stdio: 'inherit',
      env: {
        ...process.env,
        ADBLOCK: '1',
        NODE_ENV: 'development',
        DISABLE_OPENCOLLECTIVE: '1',
      },
    })
    child.on('close', (code) => {
      if (code !== 0) {
        reject({ command: `${packageManager} ${args.join(' ')}` })
        return
      }
      resolve()
    })
  })
}
```
Sources: [packages/create-next-app/helpers/install.ts:11-50](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/install.ts#L11-L50)

## App Router and Tailwind Layouts

### Overview

Templates configured for the App Router utilize a structured setup across TypeScript and JavaScript variants. The configuration files establish the typing foundation for Next.js projects using TypeScript definitions while leaving inline placeholders for user-defined options.
Sources: [packages/create-next-app/templates/app-tw-empty/ts/next.config.ts:1-8](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw-empty/ts/next.config.ts#L1-L8), [packages/create-next-app/templates/app-tw/ts/next.config.ts:1-8](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw/ts/next.config.ts#L1-L8), [packages/create-next-app/templates/app-empty/ts/next.config.ts:1-8](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-empty/ts/next.config.ts#L1-L8)

### NextConfig TypeScript Setup

The base TypeScript configuration file imported across empty and Tailwind-enabled App Router templates defines a strictly typed `NextConfig` object exported as the default module.
Sources: [packages/create-next-app/templates/app-tw-empty/ts/next.config.ts:1-8](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw-empty/ts/next.config.ts#L1-L8), [packages/create-next-app/templates/app-tw/ts/next.config.ts:1-8](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw/ts/next.config.ts#L1-L8), [packages/create-next-app/templates/app-empty/ts/next.config.ts:1-8](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-empty/ts/next.config.ts#L1-L8)

```typescript
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;
```
Sources: [packages/create-next-app/templates/app-tw-empty/ts/next.config.ts:1-8](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw-empty/ts/next.config.ts#L1-L8)

### Tailwind CSS Page Layout Structure

Tailwind-enabled templates include pre-styled page components under the App Router structure. The default component renders a flexible container layout incorporating responsive sizing, font styling, dark mode support via `dark:` modifiers, and external links to Vercel templates, learning resources, and documentation.
Sources: [packages/create-next-app/templates/app-tw/js/app/page.js:1-66](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw/js/app/page.js#L1-L66)

```javascript
import Image from "next/image";

export default function Home() {
  return (
    <div className="flex flex-col flex-1 items-center justify-center bg-zinc-50 font-sans dark:bg-black">
      <main className="flex flex-1 w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
        <Image
          className="dark:invert"
          src="/next.svg"
          alt="Next.js logo"
          width={100}
          height={20}
          priority
        />
        <div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
          <h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
            To get started, edit the page.js file.
          </h1>
          <p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
            Looking for a starting point or more instructions? Head over to{" "}
            <a
              href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
              className="font-medium text-zinc-950 dark:text-zinc-50"
            >
              Templates
            </a>{" "}
            or the{" "}
            <a
              href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
              className="font-medium text-zinc-950 dark:text-zinc-50"
            >
              Learning
            </a>{" "}
            center.
          </p>
        </div>
        <div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
          <a
            className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
            href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
            target="_blank"
            rel="noopener noreferrer"
          >
            <Image
              className="dark:invert"
              src="/vercel.svg"
              alt="Vercel logomark"
              width={16}
              height={14}
            />
            Deploy Now
          </a>
          <a
            className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
            href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
            target="_blank"
            rel="noopener noreferrer"
          >
            Documentation
          </a>
        </div>
      </main>
    </div>
  );
}
```
Sources: [packages/create-next-app/templates/app-tw/js/app/page.js:1-66](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/app-tw/js/app/page.js#L1-L66)

## Pages Router Template Architecture

### Overview

Pages Router templates provided by `create-next-app` structure initial project files under the `pages/` directory. These templates incorporate Google Fonts via `next/font/google`, CSS modules or Tailwind CSS, and metadata control using `next/head`.
Sources: [packages/create-next-app/templates/default/js/pages/index.js:1-24](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default/js/pages/index.js#L1-L24), [packages/create-next-app/templates/default-tw/js/pages/index.js:1-12](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default-tw/js/pages/index.js#L1-L12)

### Font Integration and Configuration

Pages Router starter files instantiate font loaders from `next/font/google` for variable typography. Both standard and Tailwind variants configure `Geist` and `Geist_Mono` with Latin subsets and CSS variable mappings.
Sources: [packages/create-next-app/templates/default/js/pages/index.js:3-14](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default/js/pages/index.js#L3-L14), [packages/create-next-app/templates/default-tw/js/pages/index.js:2-12](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default-tw/js/pages/index.js#L2-L12), [packages/create-next-app/templates/default-tw/ts/pages/index.tsx:2-12](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default-tw/ts/pages/index.tsx#L2-L12)

```javascript
import { Geist, Geist_Mono } from "next/font/google";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});
```
Sources: [packages/create-next-app/templates/default/js/pages/index.js:3-14](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default/js/pages/index.js#L3-L14)

> [!NOTE]
> Font variables defined through `next/font/google` are injected directly into root container class names alongside module styles or utility classes.
> Sources: [packages/create-next-app/templates/default/js/pages/index.js:25-27](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default/js/pages/index.js#L25-L27)

### Document Head and Metadata

Standard Pages Router templates import `Head` from `next/head` inside `pages/index.js` to render document-level metadata including page title, meta description, viewport settings, and favicon links.
Sources: [packages/create-next-app/templates/default/js/pages/index.js:1-24](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default/js/pages/index.js#L1-L24)

```javascript
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
```
Sources: [packages/create-next-app/templates/default/js/pages/index.js:19-24](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default/js/pages/index.js#L19-L24)

### Template Variants Comparison

The Pages Router templates provide different styling integrations across JavaScript and TypeScript flavors.

| Template Variant | File Path | Styling Mechanism | Metadata Provider |
| :--- | :--- | :--- | :--- |
| Default JS | `packages/create-next-app/templates/default/js/pages/index.js` | CSS Modules (`@/styles/Home.module.css`) | `next/head` |
| Default Tailwind JS | `packages/create-next-app/templates/default-tw/js/pages/index.js` | Tailwind CSS utility classes | Root layout wrapper |
| Default Tailwind TS | `packages/create-next-app/templates/default-tw/ts/pages/index.tsx` | Tailwind CSS utility classes | Root layout wrapper |

Sources: [packages/create-next-app/templates/default-tw/js/pages/index.js:1-79](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default-tw/js/pages/index.js#L1-L79), [packages/create-next-app/templates/default/js/pages/index.js:1-88](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default/js/pages/index.js#L1-L88), [packages/create-next-app/templates/default-tw/ts/pages/index.tsx:1-79](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/default-tw/ts/pages/index.tsx#L1-L79)

## Remote Example Streaming and Extraction

### Remote Example Streaming and Extraction

`create-next-app` handles remote examples by inspecting GitHub URLs, validating repository existence via GitHub REST endpoints, fetching gzipped tarballs from `codeload.github.com`, and piping them through the `tar` extractor with path filtering.
Sources: [packages/create-next-app/helpers/examples.ts:1-148](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L1-L148)

### GitHub URL Inspection and Validation

When an example argument is passed, `createApp` parses it as a `URL` object. If valid, it verifies that the origin equals `https://github.com`. The helper function `getRepoInfo` splits the pathname into path segments (`[, username, name, t, _branch, ...file]`) to extract repository metadata. If `t` (such as `tree`) is missing or empty, it queries `https://api.github.com/repos/${username}/${name}` to resolve the repository's default branch.
Sources: [packages/create-next-app/create-app.ts:71-96](https://github.com/blade47/next.js/blob/main/packages/create-next-app/create-app.ts#L71-L96), [packages/create-next-app/helpers/examples.ts:23-62](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L23-L62)

Repository presence is validated by `hasRepo`, which performs an HTTP `HEAD` request via `isUrlOk` to check if `package.json` exists in the target repository contents URL at the specified branch reference. If the input is not a URL, `existsInRepo` checks the Vercel Next.js repository examples folder directly.
Sources: [packages/create-next-app/helpers/examples.ts:14-87](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L14-L87)

| Helper Function | Input Parameters | Validation Method | Purpose |
| :--- | :--- | :--- | :--- |
| `isUrlOk` | `url: string` | `fetch(url, { method: 'HEAD' })` | Returns `true` if HTTP status is `200`. |
| `getRepoInfo` | `url: URL, examplePath?: string` | Pathname string splitting | Extracts `username`, `name`, `branch`, and `filePath`. |
| `hasRepo` | `RepoInfo` object | `isUrlOk` on GitHub contents API | Confirms repository and `package.json` exist. |
| `existsInRepo` | `nameOrUrl: string` | `isUrlOk` on Vercel examples path | Validates built-in Vercel repository examples. |

Sources: [packages/create-next-app/helpers/examples.ts:14-87](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L14-L87)

### Tar Stream Fetching and Pipeline Extraction

Once repository info is verified, `downloadAndExtractRepo` or `downloadAndExtractExample` fetches the tarball stream and extracts it into the target directory. 
Sources: [packages/create-next-app/helpers/examples.ts:99-147](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L99-L147)

The download call chain executes through the following steps:
`downloadAndExtractRepo()` → `downloadTarStream()` → `fetch()` → `Readable.fromWeb()` → `pipeline()` → `x()` (tar extractor).
Sources: [packages/create-next-app/helpers/examples.ts:89-130](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L89-L130)

> [!NOTE]
> `downloadTarStream` validates that `res.body` is present before wrapping the Web API `ReadableStream` into a Node.js `Readable` stream using `Readable.fromWeb()`.
> Sources: [packages/create-next-app/helpers/examples.ts:89-97](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L89-L97)

The tar extraction filter normalizes Windows path separators to POSIX style (`posix.sep`) and dynamically determines the unpacked root directory from the first path segment. This prevents failures if a repository has been renamed on GitHub while an old name was used in the URL.
Sources: [packages/create-next-app/helpers/examples.ts:111-128](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L111-L128)

### Example Extraction Workflow Implementation

```typescript
export async function downloadAndExtractRepo(
  root: string,
  { username, name, branch, filePath }: RepoInfo
) {
  let rootPath: string | null = null
  await pipeline(
    await downloadTarStream(
      `https://codeload.github.com/${username}/${name}/tar.gz/${branch}`
    ),
    x({
      cwd: root,
      strip: filePath ? filePath.split('/').length + 1 : 1,
      filter: (p: string) => {
        const posixPath = p.split(sep).join(posix.sep)
        if (rootPath === null) {
          const pathSegments = posixPath.split(posix.sep)
          rootPath = pathSegments.length ? pathSegments[0] : null
        }
        return posixPath.startsWith(
          `${rootPath}${filePath ? `/${filePath}/` : '/'}`
        )
      },
    })
  )
}
```
Sources: [packages/create-next-app/helpers/examples.ts:99-130](https://github.com/blade47/next.js/blob/main/packages/create-next-app/helpers/examples.ts#L99-L130)

## Related

- [Quick Start](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/getting-started/quick-start)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/llms.txt) for all pages in this wiki.
