Relevant source files
The following files were used as context for generating this wiki page:
- packages/create-next-app/index.ts
- packages/create-next-app/create-app.ts
- packages/next/src/build/index.ts
- packages/next/taskfile.js
- packages/next/src/bin/next.ts
- packages/create-next-app/templates/index.ts
- packages/create-next-app/helpers/examples.ts
- packages/next/src/cli/next-dev.ts
- packages/create-next-app/templates/app/js/app/page.js
- packages/next/src/cli/next-build.ts
- packages/create-next-app/templates/default/js/pages/index.js
- run-evals.js
- packages/create-next-app/templates/default-tw/js/pages/index.js
- packages/create-next-app/templates/app-tw/js/app/page.js
- packages/next/src/cli/next-start.ts
- packages/next-codemod/bin/next-codemod.ts
- package.json
- packages/next/app.js
- packages/create-next-app/templates/app-empty/js/app/page.js
- packages/create-next-app/templates/app/ts/app/page.tsx
- packages/create-next-app/templates/default-tw/ts/pages/index.tsx
- packages/create-next-app/templates/app-tw-empty/js/app/page.js
- packages/next/package.json
- packages/create-next-app/templates/app-tw/ts/app/page.tsx
- packages/create-next-app/templates/default/ts/pages/index.tsx
- packages/create-next-app/templates/app/ts/tsconfig.json
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 / Option | Description | Default |
|---|---|---|
--ts, --typescript | Initialize as a TypeScript project | Enabled |
--js, --javascript | Initialize as a JavaScript project | Disabled |
--tailwind | Initialize with Tailwind CSS config | Enabled |
--react-compiler | Initialize with React Compiler enabled | Disabled |
--cache-components | Initialize with Cache Components enabled | Disabled |
--eslint | Initialize with ESLint config | Disabled |
--biome | Initialize with Biome config | Disabled |
--app | Initialize as an App Router project | Disabled |
--src-dir | Initialize inside a src/ directory | Disabled |
--rspack | Enable Rspack as the bundler | Disabled |
--import-alias <prefix/*> | Specify import alias to use | @/* |
--api | Initialize a headless API using App Router | Disabled |
--empty | Initialize an empty project | Disabled |
--use-npm | Force scaffolding via npm | Disabled |
--use-pnpm | Force scaffolding via pnpm | Disabled |
--use-yarn | Force scaffolding via Yarn | Disabled |
--use-bun | Force scaffolding via Bun | Disabled |
--reset, --reset-preferences | Reset saved create-next-app preferences | Disabled |
--skip-install | Skip installing packages | Disabled |
--yes | Use saved preferences or defaults | Disabled |
-e, --example <name|url> | Bootstrap from example name or public GitHub URL | Disabled |
--example-path <path> | Specify subdirectory path for complex GitHub URLs | Disabled |
--agents-md | Include AGENTS.md for coding agents | Enabled |
--agent-feedback | Prepare anonymized Next.js feedback | Disabled |
--disable-git | Skip initializing a git repository | Disabled |
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
eslintis disabled,!eslint.config.mjsis appended to the exclusion array. - If
biomeis disabled,!biome.jsonis appended to the array. - If
tailwindis disabled orbundleris set toBundler.Turbopack,!postcss.config.mjsis 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 / Bundler | Target Config Property / Transformation | Source File & Line Range |
|---|---|---|
Bundler.Rspack | Wraps config with withRspack(nextConfig) and imports next-rspack | packages/create-next-app/templates/index.ts:101-114 |
tailwind + Turbopack | Inserts turbopack.rules["*.css"] with @tailwindcss/turbopack loader | packages/create-next-app/templates/index.ts:116-138 |
reactCompiler | Inserts boolean property reactCompiler: true | packages/create-next-app/templates/index.ts:140-153 |
cacheComponents | Inserts cacheComponents: true and partialPrefetching: true | packages/create-next-app/templates/index.ts:155-171 |
agentFeedback | Inserts 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 Template | File Path | Styling Mechanism | Root Element / Class |
|---|---|---|---|
| Standard JS | packages/create-next-app/templates/app/js/app/page.js | CSS Modules | <div className={styles.page}> |
| Standard TS | packages/create-next-app/templates/app/ts/app/page.tsx | CSS Modules | <div className={styles.page}> |
| Tailwind JS | packages/create-next-app/templates/app-tw/js/app/page.js | Tailwind CSS | flex flex-col flex-1 items-center justify-center |
| Tailwind TS | packages/create-next-app/templates/app-tw/ts/app/page.tsx | Tailwind CSS | flex flex-col flex-1 items-center justify-center |
| Empty JS | packages/create-next-app/templates/app-empty/js/app/page.js | None | <main> |
| Tailwind Empty JS | packages/create-next-app/templates/app-tw-empty/js/app/page.js | None | <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
Asset Imports and External Links
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 Purpose | Destination URL | Campaign Query Parameters |
|---|---|---|
| Templates Gallery | https://vercel.com/templates | ?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app |
| Learning Center | https://nextjs.org/learn | ?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app |
| Vercel Deployment | https://vercel.com/new | ?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app |
| Documentation | https://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 Variant | File Path | Documentation URL |
|---|---|---|
| Default CSS (JS) | pages/index.js | https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app |
| Default CSS (TS) | pages/index.tsx | https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app |
| Tailwind (JS) | pages/index.js | https://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.tsx | https://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 / Command | Target Action | Purpose |
|---|---|---|
pnpm clean | packages/** | Purges dist outputs and intermediate build artifacts across workspace packages |
pnpm build | Turborepo | Executes root build pipeline with remote caching and summarization |
pnpm build-all | Turborepo | Builds all packages including native auto binaries |
pnpm dev | packages/next | Invokes cross-env with NEXT_SERVER_NO_MANGLE=1 running taskr in development mode |
taskr release | packages/next | Clears 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
Related
On This Page
OverviewBootstrapping with Create Next AppCLI Invocation and Argument ParsingPackage Manager Resolution and Preference ManagementInteractive Setup and Project ValidationTemplate Layout Selection and GenerationProject Template Copying and FilteringBundler and Compiler Configuration ModifiersTypeScript and Import Alias ResolutionApp Router Starter StructuresDefault Component Layouts and Styling VariantsAsset Imports and External LinksPages Router Starter StructuresTypography and Font ConfigurationMetadata and Document Head SetupComponent Layout and Asset RenderingBuilding Next.js from SourceWorkspace Compilation and Task ManagementTaskfile Watch Workflows and BundlingRelated