Documentation
Everything Nova generates, explained
Installation, CLI usage, the plugin system, architecture conventions, and deployment — the same reference that ships as docs/ inside every generated project.
Introduction
Getting started
Nova is an extensible Next.js CLI that scaffolds a production-ready App Router application — authentication, a typed API layer, internationalization, forms, testing, and an optional plugin system — instead of leaving those decisions to you on every new project.
$ npx @darkalpha/nova my-appNo install required — always runs the latest generator.
Or install it globally and use the short form:
$ npm install -g @darkalpha/nova$ nova my-appQuick start
$ npx @darkalpha/nova my-app$ cd my-app && cp .env.example .env$ npm installOnly needed if you skipped install during setup.
$ npm run devOpen http://localhost:3000 — the app runs with locale-aware routing (/en, /fa), a working token-rotation auth flow, and a typed API client pointed at API_BASE_URL.
Run nova with no arguments for a fully interactive setup — it prompts for the project name, package manager, UI library, and plugins, and validates the combination before writing a single file.
>=18.18.0, plus npm, pnpm, yarn, or bun.Introduction
Why Nova
Most starters hand you a blank App Router project and leave the architectural decisions to you: how token refresh works, where validation schemas live, how the API client is structured. Nova answers those questions up front so you don't relitigate them on every project — and stays a plain, ownable Next.js codebase once it's generated, with no runtime dependency on the nova package.
- Composable plugins — pick only what you need, and layer more on later with
nova add. - Swappable technologies — eight UI libraries, multiple data and auth layers, no forced defaults.
- Documented architecture — generated projects ship their own
docs/folder and module-local READMEs. - Predictable generation — plugin selections are validated before any file is written, and a failed generation rolls back cleanly instead of leaving a half-built project on disk.
CLI
CLI usage
Nova has three entrypoints: generating a new project, adding features to an existing one, and inspecting plugins.
nova [project-name] [options]
nova add <feature...> [options]
nova plugins [feature]| Flag | Description |
|---|---|
-h, --help | Show the help message |
-v, --version | Print the installed version |
Examples
$ nova my-app$ novaFully interactive setup
$ nova add prisma redis$ nova plugins prismaProject names may only contain lowercase letters, numbers, dashes, and underscores (^[a-z0-9-_]+$). Invalid names are rejected before any files are written.
Running in CI
With CIset in the environment, Nova skips the "install dependencies now?" prompt and switches its logger to a quieter, CI-friendly level:
$ CI=true npx @darkalpha/nova my-appCLI
nova add
Copies an addon's files into a project that already exists and merges its dependencies and scripts into that project's package.json — the incremental counterpart to selecting a plugin at scaffold time.
$ nova add <feature...> [options]Omit the feature list for an interactive multiselect with the same options as initial generation.
| Flag | Description |
|---|---|
--path, -p <dir> | Target project directory (default: current directory) |
--force, -f | Overwrite files that already exist instead of skipping them |
$ cd my-app && nova add prisma redis$ nova add tanstack-query --path ./my-app$ nova add sentry --forceWhat it does
- Reads the target's
package.json— the directory must already be a Node/Next.js project. - Detects whether the project uses a
src/directory and remaps addon files accordingly. - Creates whatever intermediate folders are needed.
- Merges dependencies, devDependencies, and scripts from
src/featureContributions.ts— the same source full generation reads, so a feature installs identically either way. - Skips files that already exist, so re-running is safe — pass
--forceto overwrite.
next.config.mjs, middleware.ts) aren't replayed by nova add — see each plugin's docs/*.md for any lines you need to wire by hand.CLI
nova plugins
Inspect what a plugin does before adding it, without reading source files.
$ nova pluginsList every plugin with its constraints and package.json footprint
$ nova plugins prismaShow detail for a single plugin
Reads from the same metadata (src/generator/pluginMetadata.ts) and package contribution data (src/featureContributions.ts) that generation itself uses, so the output can never drift from what nova <name> or nova add actually do.
Building blocks
Plugins & add-ons
Every plugin can be selected at generation time, added later with nova add, and inspected any time with nova plugins.
| Category | Options |
|---|---|
| Data and Backend | Prisma ORM, Better Auth, Drizzle ORM, Redis, Strapi CMS, OpenAPI typed client |
| Data Fetching and State | TanStack Query, TanStack Table, Zustand, MSW API mocking |
| Testing | Vitest, Playwright, Cypress, Storybook |
| Content and Communication | React Email, Mailpit, Tiptap rich text editor |
| Infrastructure and Operations | Docker, Docker Compose, Husky + lint-staged, PWA, Bundle Analyzer, Sentry, Health/readiness endpoints, Security headers |
| Design and UX | Design System, Animations, Recharts |
Each plugin is a self-contained overlay under templates/addons/<name> — enabling it copies its files on top of the base template and wires in dependencies, scripts, and environment variables automatically. Declarative metadata (requires/conflicts/supportedUI) is validated against your full selection before any files are written.
Building blocks
UI frameworks
Nova supports eight UI approaches, wired with theming, dark mode, and a demo dashboard.
| Select | Library | Notes |
|---|---|---|
shadcn | shadcn/ui (default) | Tailwind CSS, Radix UI primitives, source-based, accessible |
mui | Material UI | MUI components, theme config, App Router cache provider |
chakra | Chakra UI | Chakra provider, theme config, component examples |
ant | Ant Design | Ant Design components, ConfigProvider, theme support |
mantine | Mantine | Mantine provider, theme config, components |
hero | HeroUI | HeroUI provider, modern component primitives |
daisy | DaisyUI | Tailwind plugin, theme presets |
headless | Headless UI | Headless UI primitives, Tailwind integration, Heroicons |
nova addcan't swap the provider tree for you.Building blocks
Project architecture
Generated applications follow a feature-first architecture.
src/
├── app/ # App Router routes, grouped under [locale]
├── components/
│ ├── ui/ # shadcn/ui-style primitives
│ ├── layout/ # Header, footer, switchers
│ ├── forms/ # Form wrapper, field, error components
│ └── providers/ # Client-side provider wrappers
├── features/ # Feature-first modules (auth, dashboard...)
│ └── <feature>/
│ ├── components/
│ ├── hooks/
│ ├── actions/
│ ├── schemas/
│ └── types/
├── lib/
│ ├── api/ # Type-safe fetch client + interceptors
│ ├── auth/ # Token rotation, session helpers
│ ├── prisma/ # Prisma client singleton
│ ├── validations/ # Shared zod schemas
│ └── cache/ # Cache tag registry
├── services/ # Business-shaped calls, built on lib/api
├── utils/ # Pure utility functions
├── i18n/ # next-intl routing/navigation config
└── messages/
├── en/
└── fa/Rule of thumb
features/owns anything specific to one product area — start here for new work.lib/owns cross-cutting infrastructure: HTTP, auth, database.components/owns reusable UI with no business logic.services/is the only place allowed to calllib/apidirectly for business data — features call services, not the API layer, so the transport can change independently.
Shipping
Environment variables
Generated projects include a .env.example covering every variable the scaffold understands, grouped by category:
- App — public URL/name, safe to expose via
NEXT_PUBLIC_* - Database —
DATABASE_URL, used by Prisma if enabled - Authentication — token secrets/TTLs, or Better Auth secrets
- External APIs — base URL/timeout for
src/lib/api - Sentry — DSNs and trace sample rates, when enabled
.env is never committed. Adding a plugin later with nova add copies files and merges package.json, but doesn't append to .env.example automatically — check that plugin's docs/*.md.Shipping
Deployment
Vercel (recommended default)
Push to a connected git repository — Vercel auto-detects Next.js. Set the environment variables from .env.example in the project settings.
Docker (if selected during generation)
$ docker build -t app .$ docker run -p 3000:3000 --env-file .env appThe generated Dockerfile uses a multi-stage build (deps → build → runtime) and Next.js output: "standalone" for a minimal production image. Every variable in .env.example must be set in production.
Shipping
FAQ & troubleshooting
Common errors
Shipping
Contributing
Before submitting changes:
$ npm install$ npm run typecheck$ npm run verify:manifest-sync$ npm run build$ node scripts/smoke-test.mjsWhen contributing a new plugin or UI integration:
- Keep the plugin isolated and avoid unnecessary dependencies.
- Declare its
package.jsonfootprint once, insrc/featureContributions.ts. - Declare metadata and constraints in
src/generator/pluginMetadata.ts. - Prefer a new contribution in
src/generator/patchers/over a newifbranch ingenerator.ts. - Add documentation and smoke-test coverage.
- Run
npm run verify:manifest-syncbefore opening a PR that touches package.json contributions.