Skip to main content
doc0blade47/next.jsdocumentation home
Sign in

Quick Start

Last updated Oct 12, 2026100% grounded
Relevant source files

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

Overview

Getting started with Next.js involves initializing development environments, configuring project scaffolding via Create Next App, and compiling the framework packages from source. These foundational workflows establish clean architectural starting points for both modern App Router and classic Pages Router applications. Sources: packages/create-next-app/index.ts:50-57, packages/create-next-app/create-app.ts:72-73, packages/next/taskfile.js:2785-2788

Bootstrapping with Create Next App

CLI Invocation and Argument Parsing

The Create Next App entry point is implemented in packages/create-next-app/index.ts using Commander. It configures the root command with version output (-v, --version), help options (-h, --help), and an optional positional argument [directory] for the target project path. Signal handlers for SIGINT and SIGTERM invoke process.exit(0), while prompt state monitoring intercepts aborted prompts to restore the terminal cursor (\x1B[?25h) before exiting with status code 1. Sources: packages/create-next-app/index.ts:1-49, packages/create-next-app/index.ts:22-39

Warning

Commander does not natively support negated options. When users pass negated flags like --no-agent-feedback, Commander interprets them as the positional project name argument in the action handler, requiring explicit prefix checks against --no- to prevent misinterpreting flags as file paths. Sources: packages/create-next-app/index.ts:124-130

The CLI supports a broad range of boolean flags and options to configure project features prior to scaffolding:

Flag / OptionDescriptionDefault
--ts, --typescriptInitialize as a TypeScript projectEnabled
--js, --javascriptInitialize as a JavaScript projectDisabled
--tailwindInitialize with Tailwind CSS configEnabled
--react-compilerInitialize with React Compiler enabledDisabled
--cache-componentsInitialize with Cache Components enabledDisabled
--eslintInitialize with ESLint configDisabled
--biomeInitialize with Biome configDisabled
--appInitialize as an App Router projectDisabled
--src-dirInitialize inside a src/ directoryDisabled
--rspackEnable Rspack as the bundlerDisabled
--import-alias <prefix/*>Specify import alias to use@/*
--apiInitialize a headless API using App RouterDisabled
--emptyInitialize an empty projectDisabled
--use-npmForce scaffolding via npmDisabled
--use-pnpmForce scaffolding via pnpmDisabled
--use-yarnForce scaffolding via YarnDisabled
--use-bunForce scaffolding via BunDisabled
--reset, --reset-preferencesReset saved create-next-app preferencesDisabled
--skip-installSkip installing packagesDisabled
--yesUse saved preferences or defaultsDisabled
-e, --example <name|url>Bootstrap from example name or public GitHub URLDisabled
--example-path <path>Specify subdirectory path for complex GitHub URLsDisabled
--agents-mdInclude AGENTS.md for coding agentsEnabled
--agent-feedbackPrepare anonymized Next.js feedbackDisabled
--disable-gitSkip initializing a git repositoryDisabled

Sources: packages/create-next-app/index.ts:50-122

Package Manager Resolution and Preference Management

Package manager selection evaluates explicit CLI flags in sequence before falling back to environment detection. If none of --use-npm, --use-pnpm, --use-yarn, or --use-bun are passed, the CLI invokes getPkgManager() to inspect the invoking user agent environment. Sources: packages/create-next-app/index.ts:137-146

const packageManager: PackageManager = !!opts.useNpm
  ? 'npm'
  : !!opts.usePnpm
    ? 'pnpm'
    : !!opts.useYarn
      ? 'yarn'
      : !!opts.useBun
        ? 'bun'
        : getPkgManager()
 

Sources: packages/create-next-app/index.ts:137-146

Preferences are persisted using the conf package with projectName: 'create-next-app'. Passing --reset or --reset-preferences prompts the user for confirmation via a prompts toggle before clearing the configuration store with conf.clear(). Sources: packages/create-next-app/index.ts:148-165

Interactive Setup and Project Validation

If no positional project directory is provided via the command line, the run() function invokes an interactive prompts text prompt requesting a project name with an initial default of my-app. Input values are validated using validateNpmName wrapped around basename(resolve(name)). Sources: packages/create-next-app/index.ts:167-190

if (!projectPath) {
  const res = await prompts({
    onState: onPromptState,
    type: 'text',
    name: 'path',
    message: 'What is your project named?',
    initial: 'my-app',
    validate: (name) => {
      const validation = validateNpmName(basename(resolve(name)))
      if (validation.valid) {
        return true
      }
      return 'Invalid project name: ' + validation.problems[0]
    },
  })
 
  if (typeof res.path === 'string') {
    projectPath = res.path.trim()
  }
}

Sources: packages/create-next-app/index.ts:171-190

If projectPath remains empty after prompting, the CLI prints usage instructions displaying the dynamic executable name (opts.name()) and terminates with exit code 1. When a path is successfully resolved, validateNpmName runs again against the computed appName before proceeding to template generation and file extraction. Sources: packages/create-next-app/index.ts:192-214

Template Layout Selection and Generation

Project Template Copying and Filtering

The template generation pipeline is executed by the installTemplate function, which determines the target source directory by joining __dirname, the selected template string, and the mode identifier (js or ts). File copying relies on the copy utility with a base glob source of ["**"]. Depending on user flags, specific configuration files are explicitly excluded from the copy operation:

  • If eslint is disabled, !eslint.config.mjs is appended to the exclusion array.
  • If biome is disabled, !biome.json is appended to the array.
  • If tailwind is disabled or bundler is set to Bundler.Turbopack, !postcss.config.mjs is excluded.
const isApi = template === "app-api";
const templatePath = path.join(__dirname, template, mode);
const copySource = ["**"];
if (!eslint) copySource.push("!eslint.config.mjs");
if (!biome) copySource.push("!biome.json");
if (!tailwind || bundler === Bundler.Turbopack) {
  copySource.push("!postcss.config.mjs");
}
 

Sources: packages/create-next-app/templates/index.ts:72-80

The file renaming function maps specific source filenames to destination filenames during extraction. Specifically, gitignore is prefixed with a dot to become .gitignore, and README-template.md is renamed to README.md to avoid being ignored by asset relocation utilities. All other filenames pass through unchanged.

rename(name) {
  switch (name) {
    case "gitignore": {
      return `.${name}`;
    }
    // README.md is ignored by webpack-asset-relocator-loader used by ncc:
    // https://github.com/vercel/webpack-asset-relocator-loader/blob/e9308683d47ff507253e37c9bcbb99474603192b/src/asset-relocator.js#L227
    case "README-template.md": {
      return "README.md";
    }
    default: {
      return name;
    }
  }
},

Sources: packages/create-next-app/templates/index.ts:84-98

Note

README-template.md is renamed to README.md during copying specifically because webpack-asset-relocator-loader used by ncc ignores files matching README.md patterns in templates. Sources: packages/create-next-app/templates/index.ts:89-93

Bundler and Compiler Configuration Modifiers

Post-copy configuration injection modifies either next.config.mjs or next.config.ts depending on the project mode. When bundler is set to Bundler.Rspack, next-rspack is imported and wraps the exported configuration object. When tailwind is enabled alongside Turbopack, a turbopack.rules configuration block is inserted to register @tailwindcss/turbopack loader rules for CSS files. Additional feature flags like reactCompiler, cacheComponents, and agentFeedback inject their corresponding options into the next configuration file.

Feature Flag / BundlerTarget Config Property / TransformationSource File & Line Range
Bundler.RspackWraps config with withRspack(nextConfig) and imports next-rspackpackages/create-next-app/templates/index.ts:101-114
tailwind + TurbopackInserts turbopack.rules["*.css"] with @tailwindcss/turbopack loaderpackages/create-next-app/templates/index.ts:116-138
reactCompilerInserts boolean property reactCompiler: truepackages/create-next-app/templates/index.ts:140-153
cacheComponentsInserts cacheComponents: true and partialPrefetching: truepackages/create-next-app/templates/index.ts:155-171
agentFeedbackInserts experimental: { agentFeedback: true }packages/create-next-app/templates/index.ts:173-186

Sources: packages/create-next-app/templates/index.ts:101-186

Tip

Enabling cacheComponents automatically forces partialPrefetching: true in the generated Next.js configuration because partial prefetching is a required runtime prerequisite for component caching. Sources: packages/create-next-app/templates/index.ts:155-168

TypeScript and Import Alias Resolution

TypeScript configuration files (tsconfig.json or jsconfig.json) are updated to reflect the chosen srcDir structure and custom importAlias. The compiler options path mapping for @/* is rewritten to either "./*" or "./src/*" depending on srcDir, and subsequently replaced entirely with the user-specified importAlias.

  "paths": {
    "@/*": ["./*"]
  }
},

Sources: packages/create-next-app/templates/app/ts/tsconfig.json:21-24

If the selected importAlias differs from the default @/*, a glob traversal scans the project root excluding config files, .git directories, fonts, and favicon binaries. Using a concurrency semaphore capacity of 8, every matching file updates its internal import statements by replacing @/ with the normalized custom alias prefix.

if (importAlias !== "@/*") {
  const files = await glob("**/*", {
    cwd: root,
    dot: true,
    stats: false,
    // We don't want to modify compiler options in [ts/js]config.json
    // and none of the files in the .git folder
    // TODO: Refactor this to be an allowlist, rather than a denylist,
    // to avoid corrupting files that weren't intended to be replaced
 
    ignore: [
      "tsconfig.json",
      "jsconfig.json",
      ".git/**/*",
      "**/fonts/**",
      "**/favicon.ico",
    ],
  });
  const writeSema = new Sema(8, { capacity: files.length });
  await Promise.all(
    files.map(async (file) => {
      await writeSema.acquire();
      const filePath = path.join(root, file);
      if ((await fs.stat(filePath)).isFile()) {
        await fs.writeFile(
          filePath,
          (await fs.readFile(filePath, "utf8")).replace(
            `@/`,
            `${importAlias.replace(/\*/g, "")}`,
          ),
        );
      }
      writeSema.release();
    }),
  );
}

Sources: packages/create-next-app/templates/index.ts:203-238

Warning

When a custom import alias is configured, file contents across the workspace are mutated via string replacement. Config files like tsconfig.json and asset paths including fonts and favicons are explicitly excluded via glob ignore patterns to prevent corruption. Sources: packages/create-next-app/templates/index.ts:213-220

App Router Starter Structures

Default Component Layouts and Styling Variants

The create-next-app scaffolding tool provides multiple starter page templates for the App Router, available in both JavaScript and TypeScript variants. Standard CSS Module templates import styles from "./page.module.css" and render container wrappers using modular class names such as styles.page, styles.main, and styles.intro, while Tailwind CSS templates rely directly on utility classes like flex flex-col flex-1 items-center justify-center. Empty starter variations simplify the page structure down to a single main element containing a greeting message.

Starter TemplateFile PathStyling MechanismRoot Element / Class
Standard JSpackages/create-next-app/templates/app/js/app/page.jsCSS Modules<div className={styles.page}>
Standard TSpackages/create-next-app/templates/app/ts/app/page.tsxCSS Modules<div className={styles.page}>
Tailwind JSpackages/create-next-app/templates/app-tw/js/app/page.jsTailwind CSSflex flex-col flex-1 items-center justify-center
Tailwind TSpackages/create-next-app/templates/app-tw/ts/app/page.tsxTailwind CSSflex flex-col flex-1 items-center justify-center
Empty JSpackages/create-next-app/templates/app-empty/js/app/page.jsNone<main>
Tailwind Empty JSpackages/create-next-app/templates/app-tw-empty/js/app/page.jsNone<main>

Sources: packages/create-next-app/templates/app/js/app/page.js:1-69, packages/create-next-app/templates/app/ts/app/page.tsx:1-69, packages/create-next-app/templates/app-tw/js/app/page.js:1-69, packages/create-next-app/templates/app-tw/ts/app/page.tsx:1-69, packages/create-next-app/templates/app-empty/js/app/page.js:1-7, packages/create-next-app/templates/app-tw-empty/js/app/page.js:1-7

Note

The default starter component is always exported as a default function named Home (export default function Home()), serving as the React Server Component entry point for the App Router root segment. Sources: packages/create-next-app/templates/app/js/app/page.js:4-4, packages/create-next-app/templates/app-tw/ts/app/page.tsx:3-3

Standard and Tailwind templates integrate optimized image assets via next/image, rendering both the Next.js logo from /next.svg and the Vercel logomark from /vercel.svg. The Next.js logo image component explicitly includes the priority boolean attribute to optimize the Largest Contentful Paint (LCP) metric during initial page load.

<Image
  className={styles.logo}
  src="/next.svg"
  alt="Next.js logo"
  width={100}
  height={20}
  priority
/>

Sources: packages/create-next-app/templates/app/js/app/page.js:8-15, packages/create-next-app/templates/app-tw/js/app/page.js:7-14

External anchor elements embedded within the starter pages link users directly to external resources, incorporating specific campaign query parameters across their href attributes. These links point to template galleries, learning centers, deployment platforms, and official documentation.

Link Target PurposeDestination URLCampaign Query Parameters
Templates Galleryhttps://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app
Learning Centerhttps://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app
Vercel Deploymenthttps://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app
Documentationhttps://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app

Sources: packages/create-next-app/templates/app/js/app/page.js:23-38, packages/create-next-app/templates/app/js/app/page.js:42-64

Warning

External anchor elements targeting external documentation or deployment platforms explicitly set target="_blank" alongside rel="noopener noreferrer" to prevent tab-nabbing security vulnerabilities. Sources: packages/create-next-app/templates/app/js/app/page.js:25-26, packages/create-next-app/templates/app/js/app/page.js:45-46

Pages Router Starter Structures

Typography and Font Configuration

Classic Pages Router starter templates load variable fonts using next/font/google. Both JavaScript and TypeScript variants for default CSS modules and Tailwind CSS configure the Geist and Geist_Mono font loaders with latin subsets and custom CSS variables.

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:6-14, packages/create-next-app/templates/default-tw/js/pages/index.js:4-12

Note

Font configuration variables --font-geist-sans and --font-geist-mono are attached directly to the root container class string alongside layout styles or utility classes. Sources: packages/create-next-app/templates/default/js/pages/index.js:25-27, packages/create-next-app/templates/default-tw/js/pages/index.tsx:16-18

Metadata and Document Head Setup

Default CSS module starter templates for the Pages Router include explicit document metadata using next/head. Within the exported Home component, the <Head> block injects the document title, meta description, viewport settings, and favicon link into the page header.

<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, packages/create-next-app/templates/default/ts/pages/index.tsx:19-24

Component Layout and Asset Rendering

All Pages Router starter templates export a default function named Home rendering the primary landing view. The layouts incorporate next/image to render the Next.js logo from /next.svg with the priority attribute enabled, alongside the Vercel logomark from /vercel.svg.

Starter templates point to specific documentation targets depending on styling configuration. Tailwind templates link directly to the Pages Router documentation path (https://nextjs.org/docs/pages/getting-started), whereas default CSS module templates link to the general documentation root (https://nextjs.org/docs).

Template VariantFile PathDocumentation URL
Default CSS (JS)pages/index.jshttps://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app
Default CSS (TS)pages/index.tsxhttps://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app
Tailwind (JS)pages/index.jshttps://nextjs.org/docs/pages/getting-started?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app
Tailwind (TS)pages/index.tsxhttps://nextjs.org/docs/pages/getting-started?utm_source=create-next-app&utm_medium=default-template-tw&utm_campaign=create-next-app

Sources: packages/create-next-app/templates/default/js/pages/index.js:16-16, packages/create-next-app/templates/default-tw/js/pages/index.js:70-76, packages/create-next-app/templates/default/ts/pages/index.tsx:78-85, packages/create-next-app/templates/default-tw/ts/pages/index.tsx:70-76

Building Next.js from Source

Workspace Compilation and Task Management

Compiling internal repository packages and preparing runtime assets requires executing workspace build pipelines and taskfile configurations defined across package scripts. Root and package-level scripts orchestrate Turborepo and Taskr workflows to clear directories, compile typescript declarations, bundle server and client runtimes, and build native binaries.

The root workspace orchestrates concurrent compilation across packages using Turborepo and pnpm scripts. Developers can execute a full system clean via pnpm clean, which filters through package directories to purge dist folders and intermediate artifacts. Building all packages from source utilizes pnpm build or pnpm build-all, triggering remote caching and task summarization. Within the packages/next workspace directory, local development and production releases rely on taskr workflows configured in taskfile.js. The package file declares taskr requirements loading webpack, ncc, swc, and watch plugins.

Script / CommandTarget ActionPurpose
pnpm cleanpackages/**Purges dist outputs and intermediate build artifacts across workspace packages
pnpm buildTurborepoExecutes root build pipeline with remote caching and summarization
pnpm build-allTurborepoBuilds all packages including native auto binaries
pnpm devpackages/nextInvokes cross-env with NEXT_SERVER_NO_MANGLE=1 running taskr in development mode
taskr releasepackages/nextClears distribution directories and starts production build workflows

Sources: package.json:12-15, packages/next/package.json:87-104

Warning

Running pnpm clean deletes dist folders across all packages in the workspace; ensure any uncommitted build products are accounted for before purging intermediate artifacts. Sources: package.json:12-12

Taskfile Watch Workflows and Bundling

The default taskfile export clears the dist directory and initiates watch workflows mapped to individual source directories inside packages/next/src. Each source subdirectory maps to specific bundle targets and compilation routines handling server runtimes, client entrypoints, api modules, shared modules, and experimental features.

export default async function (task) {
  const opts = { dev: true }
  await task.clear('dist')
  await task.start('build', opts)
  await task.watch('src/bin', 'bin', opts)
  await task.watch('src/pages', 'pages', opts)
  await task.watch('src/server', ['server', 'server_esm', 'server_wasm'], opts)
  await task.watch('src/api', 'api_esm', opts)
  await task.watch(
    'src/build',
    ['nextbuild', 'nextbuild_esm', 'nextbuildjest'],
    opts
  )
  await task.watch(
    'src/next-devtools',
    [
      'next_devtools_entrypoint',
      'next_devtools_server',
      'next_devtools_server_esm',
      'next_devtools_shared',
      'next_devtools_shared_esm',
      'next_devtools_userspace',
      'next_devtools_userspace_esm',
    ],
    opts
  )
  await task.watch('src/experimental/testing', 'experimental_testing', opts)
  await task.watch('src/experimental/testmode', 'experimental_testmode', opts)
  await task.watch('src/export', 'nextbuildstatic', opts)
  await task.watch('src/export', 'nextbuildstatic_esm', opts)
  await task.watch('src/client', 'client', opts)
  await task.watch('src/client', 'client_esm', opts)
  await task.watch('src/diagnostics', 'diagnostics', opts)
  await task.watch('src/lib', 'lib', opts)
  await task.watch('src/lib', 'lib_esm', opts)
  await task.watch('src/cli', 'cli', opts)
  await task.watch('src/telemetry', 'telemetry', opts)
  await task.watch('src/trace', 'trace', opts)
  await task.watch(
    'src/shared',
    ['shared_re_exported', 'shared_re_exported_esm', 'shared', 'shared_esm'],
    opts
  )
}

Sources: packages/next/taskfile.js:2785-2828

Production and development bundling for application runtimes utilize dedicated webpack configurations with turbo options enabled or disabled depending on the target task variant. For instance, next_bundle_app_prod, next_bundle_app_dev, next_bundle_app_prod_turbo, and next_bundle_app_dev_turbo invoke next-runtime.webpack-config with distinct parameters for bundle types and compilation flags. Type definitions are generated via generate_types, executing pnpm run types with optional watch flags and preserving watch output when requested.

export async function generate_types(task, opts) {
  const watchmode = opts.dev
  const typesPromise = execa(
    'pnpm',
    [
      'run',
      'types',
      ...(watchmode ? ['--watch', '--preserveWatchOutput'] : []),
    ],
    { stdio: 'inherit' }
  )
  // In watch-mode the process never completes i.e. the Promise never resolve.
  // But taskr needs to know that it can start watching the files for the task it has to manually restart.
  if (!watchmode) {
    await typesPromise
  }
}

Sources: packages/next/taskfile.js:2767-2783, packages/next/taskfile.js:2909-2952

Was this page helpful?