Skip to content
Create account or Sign in
The Stripe Docs logo
/
Ask AI
Create accountSign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
APIs & SDKsHelp
Overview
Versioning
Changelog
Upgrade your API version
Upgrade your SDK version
Essentials
SDKs
API
Testing
Stripe CLI
Tools
Stripe Dashboard
Stripe Projects
    Get started
    Projects for platforms
    Provider intake
    Build templates
Workbench
Developers Dashboard
Stripe for Visual Studio Code
Terraform
Stripe Discord server
Features
Workflows
Batch jobs
Event destinations
Stripe health alertsStripe SignalsFile uploads
AI tools
Agent pluginsModel Context ProtocolAgent skillsStripe Directory
Extend Stripe
Overview
Build Stripe apps
Use apps from Stripe
Build extensions
Custom objects
Security and privacy
Security
Activity logsStripebot web crawler
Privacy
Partners
Partner ecosystem
Partner certification
United States
English (United States)
  1. Home/
  2. Developer resources/
  3. Stripe Projects
Public preview

Create a build templatePublic preview

Contribute a starter app to the Stripe Projects template registry so developers can use it to build a new app with one command.

For more details, see the Stripe CLI reference.

A build template is a working starter app that you can create a project from with stripe projects build. The app is a standalone GitHub repo containing app code, config files, and deployment setup. A short manifest in the template registry points to that repository and declares which Stripe Projects services the app uses. By contributing a template to the registry, you make it discoverable by framework, provider, or use case.

How it works

Use one command to build a starter app. You need the following:

  • The Stripe CLI: Runs stripe projects build. It reads the registry, copies the template files, installs dependencies, and provisions services. You don’t change the CLI to publish a template.
  • The template registry: A shared, public repo where each template gets a short YAML manifest. The manifest tells the CLI the location of your repo, which framework it uses, and what services it needs. You add your template by opening a pull request against this repo.
  • Your template repo: A public GitHub repo with a working starter app. You own it, maintain it, and control updates. The registry never holds your code, only a pointer to it and a pinned commit.

When a developer selects your template, the CLI:

  1. Reads the manifest from the registry.
  2. Copies the template files from your repo at the pinned commit into a new project directory.
  3. Runs the install command.
  4. Sets up the Stripe project workspace.
  5. Provisions the declared services.
  6. Prints the next steps you defined.

Developer discovery

Every template in the registry is searchable by name, description, tags, and owner. Developers can browse or search and select your template directly.

stripe projects build also offers a guided flow that narrows down templates step by step. It asks what type of app the developer is building (the category), then which framework they want, then their expected traffic. It filters the registry to matching templates and presents a recommendation.

Output
What type of application are you building? Use ↑/↓ to move, Enter to select, Esc to cancel ╭──────────────────────────────────────────────────────────────────────╮ │ SaaS App │ │ ──────────────────────────────────────────────────────────────────── │ │ Subscription-based application with recurring billing. │ │ │ │ 4 templates available │ ╰──────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────╮ │ One-time payment app │ │ ──────────────────────────────────────────────────────────────────── │ │ Sell products or services with a single checkout. │ │ │ │ 5 templates available │ ╰──────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────╮ │ Static site │ │ ──────────────────────────────────────────────────────────────────── │ │ Marketing page, docs, or content site with Stripe checkout. │ │ │ │ 1 template available │ ╰──────────────────────────────────────────────────────────────────────╯

After the developer answers the prompts, the CLI shows a recommended template:

Output
Recommended Stack ╭──────────────────────────────────────────────────────────────────────╮ │ Next.js SaaS Starter │ │ ──────────────────────────────────────────────────────────────────── │ │ Description Subscription SaaS with auth, database, and billing │ │ Owner stripe │ │ │ │ Tier Free / lowest cost │ │ │ │ Vercel (hosting) $0/mo │ │ • An application deployed from a Git repository... │ │ │ │ Clerk (auth) $0/mo │ │ • Clerk Authentication - drop-in auth for any... │ │ │ │ Neon Postgres (database) $0/mo │ │ • Postgres with built-in auth - by Databricks │ │ │ │ Variants Vercel • Neon • Clerk │ │ Netlify • Render Postgres • Clerk │ │ Vercel • Render Postgres • Clerk │ │ Netlify • Neon • Clerk │ ╰──────────────────────────────────────────────────────────────────────╯

Build a template

Create your template repo

Set up a public GitHub repo containing everything you need to clone, install, and run the project: app code, package files, deployment config, and a README. One repo can hold a single template at its root, or several templates in separate subdirectories.

The registry points at a specific commit, so updates don’t affect existing users until you bump the pinned ref.

Your template code must use the services listed in your manifest. When the CLI provisions a service (for example, neon/postgres), it produces environment variables (for example, DATABASE_URL). Your template reads from those environment variables so that everything works immediately after setup, with no manual configuration. Build your app to use the environment variables that each service in your services list provides, and the CLI handles the rest.

Write the manifest

The template registry is a public, open-source repo. It holds only manifests, not app code, so each manifest points to a public GitHub repo and a pinned commit. The repo is organized like this:

projects-template-registry/ ├── guided.yaml # Guided-flow categories, in display order ├── example/example.yaml # Commented reference manifest to copy ├── nextjs_saas/ # One directory per template family │ ├── amber-fox.yaml # One file per variant, named after the variant │ ├── harbor-mist.yaml │ └── ... ├── nextjs_one_time_payment/ │ └── ... └── simple_landing_page/ └── clear-sky.yaml

Each manifest describes one variant of a template. Group related variants in a directory named after the template family, and name each file after its variant. The file can use a .yaml or .yml extension. The filename is yours to choose, because the CLI reads the template and variant fields inside the file, not the path.

The following is a complete example manifest with comments explaining each field. You can also copy example/example.yaml from the registry as a starting point.

# Choose which guided category this template appears under. guided: category: saas # Pick the framework filter key this template should match in guided mode. framework: nextjs # Use one shared template id for all variants of the same starter. template: stripe/nextjs-saas # Give this concrete variant its own stable id. variant: amber-fox # Set this to true for the variant the CLI needs to recommend first. default: true # Write the short summary shown in the variant picker. variant_description: Vercel • Neon • Clerk # Optionally run one shell command after files are copied into the new project. install_command: npm install metadata: # Show this human-friendly name in browse results and confirmation cards. name: Next.js SaaS Starter # Explain in one line what the starter gives the user. description: Subscription SaaS with auth, database, and billing # Name the team or person maintaining this template. owner: stripe # Add optional search keywords to improve browse and search results. tags: - Billing - SaaS - Next.js # Point to the repo directory the CLI should copy from. repo: https://github.com/stripe/projects-templates/tree/main/nextjs_saas_amber-fox # Pin the exact commit so users get a reproducible template. ref: 84315765f28e9ad2d0b3c7167447edf6f65bcebe # List the provider services the CLI should provision. services: - vercel/project - clerk/auth - neon/postgres # Optionally list the commands the CLI should print after setup finishes. next_steps: # Use a short heading so users know what this command is for. - label: Run locally # Print the exact command the user should run next. command: npm run dev # Add as many labeled next-step commands as you want. - label: Build product with Codex command: codex "Help me turn this into a real product. Follow prompts/starter-to-product.md." - label: Build product with Claude command: claude "Help me turn this into a real product. Follow prompts/starter-to-product.md." - label: Deploy command: npm run deploy

Test app locally

You don’t need to open a registry pull request to try your template. While you’re developing, point the CLI straight at a local manifest file:

Command Line
stripe projects build my-app --template-manifest /absolute/path/to/manifest.yaml

This is the fastest loop, and it works before your repo is public. While the template is still in development, you can leave ref empty in the local manifest.

To preview how your template appears in the full guided flow, point the CLI at a local checkout of the registry instead. Clone the registry, add your manifest to the checkout, then set STRIPE_PROJECTS_REGISTRY_PATH to the registry directory:

Command Line
git clone https://github.com/stripe/projects-template-registry.git STRIPE_PROJECTS_REGISTRY_PATH=/absolute/path/to/projects-template-registry stripe projects build

To skip the guided picker and select a template directly, pass --template. It accepts either the full variant ID (template/variant) or just the template (template):

Command Line
stripe projects build my-app --template stripe/nextjs-saas/amber-fox

Submit to the registry

When your template works locally and your repo is public, publish it so other developers can find it:

  1. Push your template repo to a public GitHub repo and choose the exact commit you want users to receive.
  2. Fork the template registry and add your manifest as <template-family>/<variant>.yaml.
  3. Set repo to your public repo (use a /tree/<branch>/<subdirectory> URL if the template is in a subdirectory) and set ref to the pinned commit.
  4. Open a pull request against the registry.

The registry entry is only an index record. Your code stays in your own repo, and you control updates by bumping the pinned ref.

Manifest field reference

Each manifest is a YAML file that describes one variant of a template. The following sections cover every field the registry parser accepts.

Guided flow categories and frameworks

Every manifest must include guided.category and guided.framework, which determine where your template appears in the guided flow. The available categories are saas (SaaS App), one_time_payment (One-time payment app), and static_site (Static site). If guided.category doesn’t match one of these keys, your template appears under “Something else” in the guided flow. Frameworks use lowercase identifiers such as nextjs and tanstack-start. If you pick “SaaS App” and then “Next.js”, your template appears in the results if it has category: saas and framework: nextjs.

If your template has multiple variants (for example, one using Vercel and Neon and Clerk, and another using Cloudflare and Turso and Auth0), the guided flow groups them by template and shows a variant picker so the developer can choose between them.

Required fields

Every manifest must include these fields. The registry parser rejects entries that are missing any of them.

Field Description
guided.categoryThe app type category. Must match ^[a-z0-9][a-z0-9_-]*$. Determines which group your template is part of during the guided flow. Also used for browse and search tag derivation.
guided.frameworkThe framework identifier. Same format as category. Determines which framework filter applies to your template in the guided flow.
templateThe logical grouping key for variants. All variants of the same starter share this value, for example stripe/nextjs-saas.
variantThe concrete variant ID within a template group. The runtime ID becomes ${template}/${variant} (for example, stripe/nextjs-saas/amber-fox).
defaultControls variant ordering within a template group. true sorts before false, then ties sort alphabetically by variant name.
variant_descriptionText shown in the guided variant picker, typically a list of key providers (for example, Vercel • Neon • Clerk). Write it exactly as you want it displayed.
metadata.namePrimary display name shown in browse cards and confirmations.
metadata.descriptionOne-line explanation of what the starter gives the user.
metadata.ownerWho maintains the template. Shown in browse cards.
repoSource repo or tree URL the template materializes from. Typically a GitHub tree URL pointing at a repo subdirectory.
refPinned commit SHA for reproducible materialization. Users always get this exact snapshot. Update this when you want users to get a newer version.
servicesList of provisioned Projects service identifiers in provider/service format (for example, vercel/project, clerk/auth, neon/postgres). The CLI provisions these automatically when a user selects the template.

Optional fields

Add these fields when they improve the user experience for your template.

Field Description
metadata.tagsFree-form browse and search tags. Search uses these plus derived tags from guided.category and guided.framework. Add tags for technologies or providers not captured by required fields.
install_commandShell command the CLI runs after files are copied into the new project. Defaults to npm install if you omit it. Can be a compound command (for example, pnpm install && pnpm generate). Use this to install dependencies, run code generation, or perform any other one-time setup the template needs before you can start working.
service_overridesOverride presentation metadata for a specific service without changing provisioning. Keyed by service identifier. Supported subfields: label (overrides display name) and category (overrides presentation category).
next_stepsList of commands the CLI prints after setup finishes, giving the developer a clear path forward. Each item has a label (a short heading describing what the command does) and a command (the exact command to print). You can include as many items as you want: running locally, building with a coding agent, deploying, or anything else relevant to your template.
tier_plansMaps guided traffic tiers to a specific provider plan per service, so the CLI can provision without prompting. See Tier plans.

Tier plans

Use tier_plans to map guided traffic tiers to specific plans for each service. Keyed by provisioned service identifier, each tier accepts either a plan identifier string or a configuration object:

# String form tier_plans: vercel/project: free_lowest_cost: Vercel/hobby starter_paid: Vercel/pro higher_scale: Vercel/pro # Config form tier_plans: cloudflare/workers: free_lowest_cost: plan: workers:free starter_paid: plan: workers:paid higher_scale: plan: workers:paid

Supported tier keys: free_lowest_cost, starter_paid, higher_scale.

Requirements

Every template must meet these requirements:

  1. Run locally with one command. After setup, the project runs without errors. Ideally, all environment variables are provided by Projects services. If you need additional variables, document them in an .env.example file.
  2. Include at least one Stripe Projects service. The template must use at least one provider available through Stripe Projects. This connects the template to the Projects ecosystem and enables automatic provisioning.
  3. Match the manifest. If your manifest lists clerk/auth and neon/postgres, your repo must use Clerk and Neon.

Troubleshooting

  • Your template doesn’t appear in the guided flow. Check that guided.category matches a key in guided.yaml, otherwise it appears under “Something else.” When testing with a local registry, confirm you added the manifest to the right directory in your checkout.
  • STRIPE_PROJECTS_REGISTRY_PATH has no effect. It must point at the registry directory, not at a single YAML file.
  • The CLI can’t find your files. If your template lives in a subdirectory, set repo to a /tree/<branch>/<subdirectory> URL that includes the subdirectory.
  • Published builds aren’t reproducible. Set ref to a pinned commit SHA. An empty ref is only for local development with --template-manifest.
  • A service still asks for input. Some providers need a plan before they can provision without prompting. Add tier_plans so the CLI can pick a plan for each traffic tier.
  • A provider fails after files are copied. The CLI still creates your project, so the developer can add or fix services afterward.

See also

  • Stripe Projects CLI
  • Provider intake for Stripe Projects
  • Projects for platforms
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Chat with Stripe developers on Discord.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc
On this page