Manifest
The .generatesaas/manifest.json file records every option your project was built with, so update can re-shape new boilerplate versions into your exact configuration.
.generatesaas/manifest.json is the record of how your project was scaffolded. It stores the full set of options you chose at init (minus secrets), so generatesaas update can re-shape each new boilerplate version into your exact configuration before diffing. It is the single input that makes updates show only changes that actually apply to your project.
You normally never edit this file by hand. init writes it, and update keeps it current. Editing an option here changes how the next update shapes the template - which is exactly how a feature gets adopted (see below).
How update keeps the manifest current
The boilerplate gains new options over time. When your project predates one, your manifest simply lacks that field. On every real update, update does two things before staging:
This runs in all four interaction modes. The new-options review always happens, even in Automatic mode (see update) - surfacing a new feature is exactly the kind of decision the update should never assume.
Init-locked vs adoptable
- Init-locked options (frontend, architecture, providers, identity) are recorded but never re-offered. Switching them after the fact is not a safe update operation - it is a migration, not an update.
- Adoptable options are features you can turn on during an update because they were added since you built. They default to off, so an existing project's behavior never changes until you choose to adopt.
Field reference
Type is the JSON value. Default is what an absent field is filled with (the behavior-preserving value). Adoptable marks options the update flow offers when they are newly available.
Project
| Field | Type | Default | Adoptable | Notes |
|---|---|---|---|---|
frontend | "nuxt" | "nextjs" | "nuxt" | No | Which frontend the project was generated with. |
Infrastructure
| Field | Type | Default | Adoptable | Notes |
|---|---|---|---|---|
architecture | "fullstack" | "separate" | "fullstack" | No | Frontend-hosted API or standalone Hono backend. |
deploymentTarget | "node" | "vercel" | "node" | No | Long-running runtime or Vercel serverless. |
databaseProvider | "postgres" | "neon" | "supabase" | "postgres" | No | Database driver and connection style. |
cacheProvider | "redis" | "upstash" | "redis" | No | Cache/session backend. |
Features
| Field | Type | Default | Adoptable | Notes |
|---|---|---|---|---|
paymentProvider | "stripe" | "polar" | "none" | "none" | No | Billing provider. |
defaultCurrency | currency code | "USD" | No | Billing and pricing currency. |
emailProvider | "smtp" | "ses" | "resend" | "smtp" | No | Transactional email provider. |
multiTenancy | boolean | false | Yes | Organizations - teams, members, shared resources. |
blog | boolean | false | Yes | The marketing blog (content collection, list and post pages). |
docs | boolean | false | Yes | The self-hosted Fumadocs docs app (apps/docs). |
desktop | boolean | false | Yes | The cross-platform desktop app (apps/electron, built with Electron). |
ai | boolean | false | Yes | The app's AI features (config.ai.enabled): chat, models, schedules, integrations. Master gate for the AI sub-options below - when off they are forced off and the AI nav self-hides. A desktop project always ships the app's local AI stack: this option sets config.desktop.agents.enabled (the runtime gate on those screens) and decides whether a companion daemon is bundled inside the packaged build. That daemon half is why it is structural - turning it on later re-runs init/update to bring the daemon source in. |
companion | boolean | false | Yes | Lets your users install a companion daemon that runs their own AI subscriptions on their hardware. Point at an existing shared companion like OpenCompanion (default), or vendor and publish your own branded daemon. Requires AI features. |
companionSource | "shared" | "vendored" | "vendored" on a desktop project with AI (it bundles its own daemon) or when companionName is already recorded, else "shared" | Yes | Where the daemon comes from: point at an existing shared companion repo, or vendor and publish your own. Requires the companion, or a desktop app with AI. A desktop app with AI bundles the daemon inside its build, so it is always "vendored" there - an explicit "shared" on such a project is rejected. |
companionRepoUrl | string | "https://github.com/Duzbee/OpenCompanion" | Yes | GitHub URL of the shared companion this project points at; its brand.json supplies the daemon identity and its latest release is what users install. Requires a shared-source companion. |
companionName | string | derived from the project name | Yes | Display name of the companion daemon this project ships (e.g. "Acme Saas Companion") - what your web users install, and what a desktop app bundles. It names the daemon's binary, its OS service and its data folder, so it is PERSISTED once and never re-derived (renaming your project must not orphan the service already installed on your users' machines). Defaults to the title-cased project name plus " Companion". Requires a bundled daemon: a vendored companion, or a desktop app with AI. |
credits | boolean | false | Yes | Metered usage credits on top of subscription plans. Requires a payment provider. |
revenueSharing | boolean | false | Yes | Opt-in MRR leaderboard with dofollow backlinks. |
Tooling
| Field | Type | Default | Adoptable | Notes |
|---|---|---|---|---|
dockerServices | string[] | [] | No | Local services scaffolded in docker-compose. |
aiTools | string[] | [] | No | Which AI assistants receive the bundled skill files. |
System fields
These are not options. They are written by init and maintained by the CLI - do not edit them.
| Field | Notes |
|---|---|
version | The boilerplate version the project is currently on. update bumps it when an apply completes. |
initialVersion | The version the project was first scaffolded from. |
repo | The source boilerplate repository. |
appName | Display name of the app. |
projectName | Slug used for the project directory and package names. |
baseUrl | Public base URL baked into config and .env, when set. |
licenseToken | Signed license token; refreshed by update for the target version. |
licenseKeyHash | Hash of the license key, for attribution. |
installId | Per-install identifier used by the heartbeat. |
Update
Pull the latest boilerplate version - the CLI stages a re-shaped template and your AI assistant applies the diff while preserving your customizations.
Licensing & Heartbeat
Learn how the license manifest and daily heartbeat validate your installation, what data the cron sends, and how to opt out permanently with eject.