Nova Config Reference
The nova.config.json file lives at the monorepo root and drives every Nova command. This page documents each section and its fields.
For your first working file, follow the first successful check. Use this reference when you need every supported field, or run nova utility initialize to edit the same schema interactively.
project
Describes the project identity, display info, and build metadata.
| Field | Type | Description |
|---|---|---|
name.slug | string | URL-safe project identifier. Letters, numbers, hyphens, and underscores only. The 214-character npm limit is enforced by the nova utility initialize wizard; the parser only requires a non-empty trimmed string. |
name.title | string | Human-readable project name for display. |
description.short | string | One-line summary used in package.json and meta tags. |
description.long | string | Extended description for README and documentation pages. |
keywords | string[] | Search keywords (max 50 characters each). |
legalName | string | Legal entity name used in LICENSE and copyright notices. |
pronouns | string | Controls first-person wording in generated files. One of "business" (we/our) or "personal" (I/my). |
platforms | string[] | Supported platforms for bug report dropdowns. One or more of "nodejs", "swift", "android", "java", "kotlin", "csharp", "php", "python", "macos", "linux", "windows". Unknown values are dropped. |
startingYear | number | Year the project began (integer >= 1970). Used in LICENSE copyright ranges. |
license | string | License identifier. One of "AGPL-3.0", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "BSL-1.0", "CC0-1.0", "EPL-2.0", "GPL-2.0", "GPL-3.0", "LGPL-2.1", "MIT", "MPL-2.0", "Proprietary", or "Unlicense". |
{
"project": {
"name": {
"slug": "example",
"title": "Example"
},
"description": {
"short": "A sample Nova project.",
"long": "Extended description for documentation and README files."
},
"keywords": ["example", "nova"],
"legalName": "Example Author LLC",
"pronouns": "business",
"platforms": ["nodejs", "macos", "linux", "windows"],
"startingYear": 2025,
"license": "MIT"
}
}
entities
An array of people and organizations associated with the project.
| Field | Type | Description |
|---|---|---|
name | string | Display name. |
email | string | Contact email (must contain @ and a domain). |
url | string | Profile or organization URL (http:// or https://). |
roles | string[] | One or more of "author", "contributor", "supporter". |
{
"entities": [
{
"name": "Example Author",
"email": "[email protected]",
"url": "https://example.com/author",
"roles": ["author"]
},
{
"name": "Example Collaborator",
"email": "[email protected]",
"url": "https://example.com/collaborator",
"roles": ["contributor", "supporter"]
}
]
}
emails
Canonical contact addresses referenced by tools and metadata.
| Field | Type | Description |
|---|---|---|
bugs | string | Email for bug reports and support. |
{
"emails": {
"bugs": "[email protected]"
}
}
github
Identifies the GitHub repository and declares repository-level settings. Most blocks are maintained by repeatable recipes; issueTemplate is input for an explicit generator.
| Field | Type | Owner command |
|---|---|---|
owner | string | Target owner used by every GitHub recipe and generator. Letters, numbers, and hyphens are allowed. |
repo | string | Target repository used by every GitHub recipe and generator. Letters, numbers, dots, _, and - work. |
topics | string[] | sync-identity. An empty array clears GitHub topics. |
features | object | sync-features. |
policies | object | sync-policies. |
security | object | sync-security. |
rulesets | object | sync-rulesets. |
actions | object | sync-actions. |
labels | object[] | sync-labels. |
issueTemplate | object | nova generate github issue-template. |
An omitted recipe field means “leave GitHub's current value alone.” It does not mean false, and Nova does not mix in GitHub defaults.
Features Fields
Booleans controlling which repository features are enabled. Each field is optional; omitted fields leave the corresponding GitHub setting untouched.
| Field | Type | Description |
|---|---|---|
issues | boolean | Enables the Issues tab. |
wiki | boolean | Enables the Wiki tab. |
projects | boolean | Enables repository Projects. |
discussions | boolean | Enables the Discussions tab. |
sponsorships | boolean | Enables the Sponsor button when GitHub considers it eligible. |
Policies Fields
Repository policy settings. Each field is optional.
| Field | Type | Description |
|---|---|---|
visibility | string | public, private, or internal. |
defaultBranch | string | Default branch name. Nova skips the update if that branch does not exist yet. |
mergeMethods.merge | boolean | Allows merge commits. |
mergeMethods.squash | boolean | Allows squash merges. |
mergeMethods.rebase | boolean | Allows rebase merges. |
mergeCommit.title | string | pull-request-title or merge-message. |
mergeCommit.message | string | pull-request-body, pull-request-title, or blank; requires mergeCommit.title. |
squashMerge.title | string | pull-request-title or commit-or-pull-request-title. |
squashMerge.message | string | pull-request-body, commit-messages, or blank; requires squashMerge.title. |
autoDeleteHeadBranch | boolean | Deletes the head branch after a pull request is merged. |
autoMerge | boolean | Allows pull-request auto-merge. |
allowUpdateBranch | boolean | Allows GitHub's update-branch action when a pull request is behind its base. |
webCommitSignoffRequired | boolean | Requires signoff for commits created through GitHub's web interface. |
Security Fields
| Field | Type | Description |
|---|---|---|
vulnerabilityAlerts | boolean | Enables Dependabot vulnerability alerts. |
dependabotSecurityUpdates | boolean | Enables automatic security-update pull requests. |
secretScanning | boolean | Enables secret scanning. |
pushProtection | boolean | Blocks pushes containing detected secrets. |
pushProtection: true requires secretScanning: true in the same block. GitHub plan and organization policies still determine availability.
Ruleset Fields
These fields configure Nova's one named default-branch ruleset, Nova default branch.
| Field | Type | Description |
|---|---|---|
defaultBranch.enforcement | string | active, disabled, or evaluate. |
blockDeletions | boolean | Blocks default-branch deletion. |
blockForcePushes | boolean | Blocks force pushes. |
requireLinearHistory | boolean | Requires linear history. |
requireSignedCommits | boolean | Requires signed commits. |
requirePullRequest | boolean | Requires pull requests. |
allowedMergeMethods | string[] | One or more of merge, squash, and rebase when pull requests are required. |
dismissStaleReviews | boolean | Dismisses approvals after new commits. |
requireCodeOwnerReview | boolean | Requires a code-owner review. |
requireLastPushApproval | boolean | Requires someone other than the last pusher to approve. |
requiredApprovals | number | Integer from 0 through 10. |
requireConversationResolution | boolean | Requires review threads to be resolved. |
requiredStatusChecks | string[] | Required status-check context names. |
requireBranchesToBeUpToDate | boolean | Requires a current branch and at least one required status check. |
At least one protection rule must be enabled. Nova does not edit or delete unrelated rulesets.
Actions Fields
| Field | Type | Description |
|---|---|---|
enabled | boolean | Enables or disables Actions. Required with allowedActions or SHA pinning. |
allowedActions | string | all, local-only, or selected. |
shaPinningRequired | boolean | Requires full-SHA action references. |
selectedActions.githubOwned | boolean | Allows GitHub-owned actions in selected mode. |
selectedActions.verified | boolean | Allows verified Marketplace creators in selected mode. |
selectedActions.patterns | string[] | Custom allowlist patterns. An empty array clears those patterns. |
defaultWorkflowPermissions | string | Default GITHUB_TOKEN permission: read or write. |
canApprovePullRequestReviews | boolean | Allows Actions to create or approve pull-request reviews. |
artifactRetentionDays | number | Integer from 1 through 400; GitHub may enforce a lower plan maximum. |
Label Fields
Each entry in labels has these fields. An explicit empty array is valid and performs no work. Labels missing from the array are not deleted.
| Field | Type | Description |
|---|---|---|
name | string | Required non-empty label name. |
color | string | Required six-digit hexadecimal color without #. |
description | string | Optional label description. |
Issue Template Fields
| Field | Type | Description |
|---|---|---|
bugReportFields | string[] | Optional platform field filenames for generated bug reports, such as nodejs.yml. When omitted, the generator derives fields from project.platforms. |
{
"github": {
"owner": "example-org",
"repo": "example-project",
"topics": ["nova", "monorepo", "typescript"],
"features": {
"issues": true,
"wiki": false,
"projects": false,
"discussions": true,
"sponsorships": true
},
"policies": {
"visibility": "public",
"defaultBranch": "main",
"mergeMethods": {
"merge": false,
"squash": true,
"rebase": false
},
"mergeCommit": {
"title": "pull-request-title",
"message": "pull-request-body"
},
"squashMerge": {
"title": "commit-or-pull-request-title",
"message": "commit-messages"
},
"autoDeleteHeadBranch": true,
"autoMerge": true,
"allowUpdateBranch": true,
"webCommitSignoffRequired": false
},
"security": {
"vulnerabilityAlerts": true,
"dependabotSecurityUpdates": true,
"secretScanning": true,
"pushProtection": true
},
"rulesets": {
"defaultBranch": {
"enforcement": "active",
"blockDeletions": true,
"blockForcePushes": true,
"requireLinearHistory": false,
"requireSignedCommits": true,
"requirePullRequest": true,
"allowedMergeMethods": ["squash", "rebase"],
"dismissStaleReviews": true,
"requireCodeOwnerReview": false,
"requireLastPushApproval": true,
"requiredApprovals": 1,
"requireConversationResolution": true,
"requiredStatusChecks": ["check", "build"],
"requireBranchesToBeUpToDate": true
}
},
"actions": {
"enabled": true,
"allowedActions": "selected",
"shaPinningRequired": true,
"selectedActions": {
"githubOwned": true,
"verified": false,
"patterns": ["actions/*", "acme/*"]
},
"defaultWorkflowPermissions": "read",
"canApprovePullRequestReviews": false,
"artifactRetentionDays": 30
},
"labels": [
{
"name": "bug",
"color": "d73a4a",
"description": "Something isn't working"
},
{
"name": "good first issue",
"color": "7057ff",
"description": "Good for newcomers"
}
],
"issueTemplate": {
"bugReportFields": ["nodejs.yml", "screenshots.yml"]
}
}
}
workflows
An array of GitHub Actions workflow entries consumed by nova generate github workflows. Each entry maps to one generated .yml file.
| Field | Type | Description |
|---|---|---|
template | string | Name of a bundled workflow template: "publish", "lock-inactive-issues", or "check-sponsor-gated-issues". |
name | string | Required label appended to the output filename and workflow name. Must be unique within the same template. |
triggers | array | Triggers for the template. Each is a bare string or an object such as { "name": "push", "branches": ["main"] }. |
build | string[] | Optional. Workspace paths (keys from workspaces) that the check / build step should filter to. |
deploy | object[] | Optional. Publish destinations for the publish template. Each destination has to, path, after, with. |
with | object | Optional. Key-value pairs that remap secret / variable names or supply values for literal template variables. |
Field names changed in the rebuilt generator: suffix is now name, scopes is now build, targets is now deploy, and settings is now with. The former top-level depends-on moved onto the workflow-run trigger object as a workflows array.
Trigger Object Fields
Use a bare string for triggers that need no filters, such as "release". Use an object when the trigger needs additional settings.
| Field | Type | Description |
|---|---|---|
name | string | Required trigger name, such as "push", "tag-push", or "workflow-run-success". |
branches | string[] | Branch filters for push. A push trigger requires at least one branch. |
paths | string[] | Optional path filters for push. |
tags | string[] | Optional tag filters for tag-push. |
workflows | string[] | Upstream {template}-{name} keys for a workflow-run-* trigger. Any listed workflow can start the downstream run; GitHub does not wait for all of them. |
{
"name": "workflow-run-success",
"workflows": ["publish-core"]
}
See Configuring Workflow-Run Triggers for chaining behavior and GitHub's limits.
Deploy Fields
Each entry in the deploy array pins one publish destination to a workspace.
| Field | Type | Description |
|---|---|---|
to | string | One of: "npm", "github-action", "github-packages", "docker-hub", "ghcr", "cloudflare-pages-docusaurus", "cloudflare-workers", "github-pages-docusaurus", "vercel-nextjs". |
path | string | Path to the workspace that owns the destination (e.g., "./packages/nova"). |
after | string[] | Optional. Paths of other same-type destinations that must finish publishing before this one starts. |
with | object | Optional. Key-value pairs for this destination that remap names or supply literal values, overriding the workflow-level with. |
Variable Formats
Each template declares variables with one of three formats. The format determines how values in with are used:
| Format | What happens |
|---|---|
secret | Produces ${{ secrets.NAME }} in the YAML. A with value remaps the secret name. |
var | Produces ${{ vars.NAME }} in the YAML. A with value remaps the variable name. |
literal | Replaces the placeholder with the exact string from with. Must be provided or the entry is skipped. |
Output Filenames
Generated files follow the pattern nova-{template}-{name}.yml under .github/workflows/.
{
"workflows": [
{
"template": "lock-inactive-issues",
"name": "project",
"triggers": ["schedule-weekly"]
},
{
"template": "publish",
"name": "project",
"triggers": ["release"],
"build": [
"./packages/core",
"./packages/preset",
"./apps/docs"
],
"deploy": [
{
"to": "npm",
"path": "./packages/core"
},
{
"to": "npm",
"path": "./packages/preset",
"after": ["./packages/core"]
},
{
"to": "cloudflare-pages-docusaurus",
"path": "./apps/docs"
}
]
}
]
}
urls
Canonical links with validation and normalization.
| Field | Type | Description |
|---|---|---|
homepage | string | Project homepage URL. |
repository | string | Source repository URL. Accepts git:, git+https:, git+ssh:, git+http:, http://, https://. |
bugs | string | Issue tracker URL. |
license | string | License file URL. |
logo | string | Project logo URL. |
documentation | string | Documentation site URL. |
npm | string | npm package page URL. |
docker | string | Docker image registry page URL. |
fundSources | string[] | Funding URLs (entered comma-separated in the wizard, saved as a list). |
privacyPolicy | string | Privacy policy URL. Appears in generated GitHub issue templates. |
termsOfUse | string | Terms of use URL. Appears in generated GitHub issue templates. |
{
"urls": {
"homepage": "https://example.com",
"repository": "https://github.com/example/example-project",
"bugs": "https://github.com/example/example-project/issues",
"license": "https://github.com/example/example-project/blob/main/LICENSE",
"logo": "https://example.com/assets/logo.svg",
"documentation": "https://docs.example.com/project",
"npm": "https://www.npmjs.com/package/example-project",
"docker": "https://hub.docker.com/r/example/example-project",
"fundSources": [
"https://github.com/sponsors/example",
"https://opencollective.com/example"
],
"privacyPolicy": "https://example.com/privacy",
"termsOfUse": "https://example.com/terms"
}
}
workspaces
A map of relative paths to workspace definitions. Each key is a path from the monorepo root (e.g., "./", "./apps/docs", "./packages/nova").
| Field | Type | Description |
|---|---|---|
name | string | Package name for package.json. Must follow the naming pattern for its role. See Workspace Rules for details. |
role | string | Workspace role: "project", "docs", "config", "app", "package", "tool", or "template". See Workspace Rules for details. |
policy | string | Workspace policy: "freezable", "trackable", or "distributable". See Workspace Rules for details. |
{
"workspaces": {
"./": {
"name": "example-project",
"role": "project",
"policy": "freezable"
},
"./packages/nova": {
"name": "@company/example",
"role": "package",
"policy": "distributable"
},
"./apps/docs": {
"name": "example-docs",
"role": "docs",
"policy": "freezable"
}
}
}
gitignore
Adds project-specific patterns to the generated root .gitignore without mixing them into Nova's built-in templates.
| Field | Type | Description |
|---|---|---|
projectExcludes | string[] | Optional patterns appended under the generated Project Excludes marker. An empty array keeps the section empty. |
{
"gitignore": {
"projectExcludes": [
".wrangler/",
"coverage/"
]
}
}
agents
Selects the AI-tool entry files emitted by nova generate must-haves agent-conventions.
| Value | File emitted |
|---|---|
"claude-code" | CLAUDE.md |
"codex" | AGENTS.md |
The shared VISION.md, PROJECT_RULES.md, and conventions/*.md files are generated whenever at least one agent is selected. An empty array is valid and intentionally disables generation.
{
"agents": ["claude-code", "codex"]
}
recipes
Stores every recipe toggle in one top-level block. Repository, license, and README recipes are project-scoped; package-json recipes are nested under the workspace path they modify.
Recipe Entry Fields
| Field | Type | Description |
|---|---|---|
enabled | boolean | Required. Runs the recipe when true and skips it when false. |
settings | object | Optional boolean settings supported by that recipe. Unknown or non-boolean settings are dropped. |
Recipe Categories
| Category | Supported recipes |
|---|---|
github | sync-actions, sync-features, sync-identity, sync-labels, sync-policies, sync-rulesets, sync-security |
license | update-copyright |
read-me | update-badges, update-credits, update-documentation, update-header, update-introduction |
package-json | cleanup, normalize-artifacts, normalize-bundler, normalize-dependencies, normalize-modules, normalize-tooling, sync-environment, sync-identity, sync-ownership |
Package JSON recipes accept these optional settings where applicable:
| Recipe | Settings |
|---|---|
cleanup | removeUnknownKeys, reorderKeys |
normalize-dependencies | pinDependencyVersions, pinDevDependencyVersions |
sync-environment | trackNodeLtsVersions |
sync-identity | description, keywords, displayName for distributable workspaces |
sync-ownership | homepage, bugs, author, contributors, funding, repository for distributable workspaces |
{
"recipes": {
"github": {
"sync-identity": {
"enabled": true
}
},
"license": {
"update-copyright": {
"enabled": true
}
},
"read-me": {
"update-header": {
"enabled": true
}
},
"package-json": {
"./": {
"cleanup": {
"enabled": true,
"settings": {
"removeUnknownKeys": true,
"reorderKeys": true
}
}
},
"./packages/nova": {
"sync-identity": {
"enabled": true,
"settings": {
"description": true,
"keywords": true,
"displayName": true
}
}
}
}
}
}
environment
Every environment value in the repository lives here, grouped by namespace and classified by its required reach. The nova generate must-haves dotenv command writes workspace values to local .env files, while publish workflows provision and deliver the non-local values.
| Field | Type | Description |
|---|---|---|
project | object | Optional. Project-wide managed keys, such as deploy credentials, under one shared prefix. See Project Fields. |
workspaces | object | Optional. Per-workspace environment values, keyed by the workspace path (including the repo root ./). See Workspaces Fields. |
workflows | object | Optional. Workflow-config prefixes, keyed by workflow name. See Workflows Fields. |
Every declared environment.project, environment.workspaces.<path> (including the repo root ./), and environment.workflows.<name> entry must declare a prefix — there is no exception for a group whose keys are all local. Nova joins that prefix to every key to form its GitHub name (for example, CBN_ joined to PUBLIC_SITE_KEY becomes CBN_PUBLIC_SITE_KEY).
Prefixes must be disjoint, must not reuse the reserved GITHUB_ namespace, and a key must not repeat its own prefix. The reserved dotenv keys NODE_ENV, LOG_LEVEL, and LOG_TIME are the only unprefixed, template-managed keys.
Project Fields
project holds project-wide keys under a single prefix. Each variable uses reach: "managed", is provisioned on GitHub, and is not written to a workspace .env or delivered to a build or server.
Project-scoped deploy credentials (such as a Cloudflare API token) also derive their GitHub name from this prefix.
| Field | Type | Description |
|---|---|---|
prefix | string | Required. The uppercase namespace joined to every key. |
variables | array | Optional. Managed-only values, each with key, reach: "managed", and secret. |
Workspaces Fields
environment.workspaces is keyed by a workspace path that matches a top-level workspaces entry (including the repo root ./). Each workspace declares a prefix; every value appears in its generated .env and .env.sample, while reach determines what happens beyond local development.
| Field | Type | Description |
|---|---|---|
prefix | string | Required. The uppercase namespace joined to every key. |
variables | array | Optional. Workspace environment values. See Value Fields. |
Value Fields
| Field | Type | Description |
|---|---|---|
key | string | Environment variable name. Nova joins the group's prefix when a non-local value needs a GitHub name; local .env files use the unprefixed key. |
reach | string | Required. One of "local", "managed", "build", or "runtime". See Reach Values. |
secret | boolean | Required for managed, build, and runtime; forbidden for local. true stores the GitHub value as a Secret, while false stores it as a Variable. |
defaultValue | string | Optional for non-secret local, build, and runtime values. Seeds .env.sample; for build, it is also the build fallback. Forbidden for managed values and every value with secret: true. |
Reach Values
| Reach | Local .env | GitHub | CI delivery |
|---|---|---|---|
local | ✓ | ✗ | None. The key stays on the developer machine. |
managed | ✓ (blank) | ✓ | None. Nova tracks the GitHub name but does not inject it into a build or server. |
build | ✓ | ✓ | Injected into the build environment. |
runtime | ✓ | ✓ | Reconciled into every server-bearing deploy target for the workspace. |
Project-scoped variables support only managed. Their Local .env column is not applicable because they do not belong to a workspace.
Workflows Fields
workflows is keyed by a workflow name and gives that workflow's config keys their own prefix.
| Field | Type | Description |
|---|---|---|
prefix | string | Required. The uppercase namespace joined to every key. |
{
"environment": {
"project": {
"prefix": "ACCT_",
"variables": [
{ "key": "NPM_TOKEN", "reach": "managed", "secret": true }
]
},
"workspaces": {
"./": {
"prefix": "ROOT_"
},
"./apps/web": {
"prefix": "WEB_",
"variables": [
{ "key": "LOCAL_API_MOCK", "reach": "local", "defaultValue": "http://127.0.0.1:8787" },
{ "key": "SENTRY_PROJECT", "reach": "managed", "secret": false },
{ "key": "PUBLIC_ANALYTICS_ID", "reach": "build", "secret": false, "defaultValue": "" },
{ "key": "STRIPE_SECRET_KEY", "reach": "runtime", "secret": true }
]
}
},
"workflows": {
"sponsor-check": {
"prefix": "SGI_"
}
}
}
}
settings
Project-wide behavior toggles that affect how Nova commands operate.
| Field | Type | Description |
|---|---|---|
lockStepVersioning | boolean | When true, nova utility changelog --release moves every non-freezable workspace — both trackable and distributable — to the same version, even if some had no recorded changes. Before writing, Nova requires every participating package.json to exist, contain a valid version for the selected strategy, and start at the same version. Workspaces without changes receive a "No changes." entry in their CHANGELOG.md. |
versionStrategy | string | Version strategy for the project: "semver" (default) or "calver". SemVer uses major.minor.patch with bump types. CalVer uses YYYY.MM.MICRO with automatic date-based versioning. Nova locks this setting to existing version headings found in the root or any non-freezable workspace changelog; missing changelogs and freezable workspaces do not lock it. |
{
"settings": {
"lockStepVersioning": true,
"versionStrategy": "semver"
}
}