Next.js
Scaffold a Next.js workspace with React, TypeScript, and the App Router.
You can run this directly from an empty location; scaffold starter base is not a prerequisite. Nova creates the monorepo root and the first Next.js workspace together.
Why Use This Command?
- Installs Next.js 16 with React 19, TypeScript, and the App Router so you can start building pages immediately.
- Auto-detects monorepo or workspace mode so the same command works whether you're starting fresh or adding to an existing project.
- Provides
dev,prod,check,build, andcleanscript groups whose top-level commands delegate to adjacentname:*steps through Nova's script runner. - Runs Next.js type generation before separate app, configuration, and Vitest type checks. Vite's test types never enter Next.js production compilation.
- Enables Nova's complete custom ESLint rules and a starter Vitest suite while leaving every rule open to consumer overrides.
- Optionally enables Next.js standalone output and contributes it to the repository-wide s6 Docker appliance.
- Starts with official App Router locale segments, server-side JSON dictionaries, and an English-default proxy without third-party i18n packages.
Requirements
- Node.js runtime — Use any Node.js LTS release.
- Empty directory (monorepo mode) or monorepo root (workspace mode) — The command auto-detects which mode to use.
Usage
Options
| Flag | Description |
|---|---|
-d, --dry-run | Run without writing any files. |
--install | Install dependencies after scaffolding; this is the default. |
--no-install | Skip dependency installation. |
--name <name> | Project slug when creating a new monorepo; omit at an existing root. |
--non-interactive | Use flags and defaults without opening prompts. |
--workspace-name <name> | Workspace directory name. |
--output <dir> | Output directory. |
--docker-image | Enable standalone output and add the Next.js service to the repository s6 image. |
Output Structure
{project-slug}/
├── package.json
├── nova.config.json
├── apps/
│ └── {workspace-name}/
│ ├── eslint.config.mts
│ ├── package.json
│ ├── next.config.mjs
│ ├── tsconfig.json
│ ├── tsconfig.config.json
│ ├── tsconfig.tests.json
│ ├── vitest.config.mts
│ ├── tests/
│ │ └── project.test.ts
│ └── src/
│ ├── app/
│ │ ├── [lang]/
│ │ │ ├── dictionaries/
│ │ │ │ └── en.json
│ │ │ ├── dictionaries.ts
│ │ │ ├── layout.tsx
│ │ │ └── page.tsx
│ │ └── globals.css
│ ├── i18n/
│ │ └── config.ts
│ └── proxy.ts
└── packages/
With --docker-image, Nova adds root .dockerignore, Dockerfile, and compose.yml entry points plus private assembly files under packages/docker. The standalone Next.js server runs as a supervised service inside the repository's one s6 image.
See Docker Images for the shared runtime and layout contract.
Localization
The generated proxy redirects unprefixed application routes to /en, and the [lang] App Router segment validates every locale before loading its server-side dictionary. English is the only initial locale, so Nova does not add browser negotiation packages that would be unnecessary in a one-language project.
Add a locale to src/i18n/config.ts, place its JSON dictionary beside en.json, and register its loader in dictionaries.ts. Next.js keeps dictionaries in Server Components, so message catalogs are not added to the client JavaScript bundle.
How It Works
Interactive Wizard
When run without flags, Nova collects every answer before it writes files:
Monorepo mode (no package.json found):
- Project name — Enter a slug for your monorepo (e.g.
my-app). - Workspace name — Enter a slug for the workspace directory (default:
nextjs).
The new project is created in ./{project-name} by default and never directly in the current directory.
Workspace mode (package.json with workspaces found):
- Workspace name — Enter a slug for the workspace directory (default:
nextjs). - Output directory — Confirm the workspace path (default:
./apps/{workspace-name}).
Nova reads the project slug from the root nova.config.json; it does not ask you to rename the project or package.
After collecting the answers, Nova displays the complete plan and asks for one confirmation. It then writes the scaffold and installs dependencies unless you pass --no-install. Project-level generators remain separate commands that you can run after configuring nova.config.json.
Non-Interactive Mode
Agents and automation should add --non-interactive. A new monorepo needs --name, --workspace-name, and --output. An existing monorepo needs only --workspace-name and --output; omit --name because Nova reads the root project slug.
Naming, Registration, and Safety
For project slug my-app and workspace slug web, Nova names the package my-app-app-web. The same name is written to the workspace package.json and its nova.config.json entry. If the root workspaces globs do not include the selected output, Nova adds that exact relative path to the root package.json.
Before writing, Nova requires a readable root package.json and nova.config.json, keeps the output inside the monorepo, rejects duplicate paths and names, and lists any template files it would overwrite. --dry-run performs these checks without changing the project.
Next Steps
After scaffolding, consider running generators to add project files like .editorconfig, LICENSE, and README.md. The root .gitignore is already generated by the scaffold.