Get started

How to Choose Templates

Decision tree for the 10 base templates. Pick the right one in 30 seconds.

6 min readUpdated 3 days agoEdit on GitHub

If you are adding a new project and do not know which base template to pick, this page gives you a decision tree and a comparison table.

If you would rather start from a complete workspace composition instead of choosing each one add template yourself, use Template Examples. That page has full starters for mobile, desktop, web, consumer, admin, and docs projects, each with a copyable one create --preset ... command.

For: people who ran one templates and saw too many IDs, tech leads evaluating stack choices, and anyone writing template-selection rules for agents.

You will learn: how to pick the right base template in 30 seconds, and when to skip the decision and use a complete example instead.

30-second Rule

Need a backend API -----------------------> nestjs-api / go-api
Need a browser-facing web project --------> nextjs-app / react-spa / astro-site
Need a reusable package ------------------> ts-library / go-lib
Need a documentation site ----------------> starlight-docs
Need a mobile app ------------------------> expo-mobile
Need a desktop app -----------------------> electron-app

If unsure, ask one question: how does the user consume this thing? Browser -> Web. Command-line / HTTP calls -> API. npm install / go get -> Library. .app / .dmg / .exe -> Desktop. App Store -> Mobile. Reading content -> Docs.

Full Comparison

IDCategoryKeywordsOne-line fitDetails
nestjs-apiAPITypeScript, NestJS, RESTDefault API template for TypeScript teamsMobile / marketing / admin examples
go-apiAPIGo, Gin, GORMHigh-throughput / low-memory / mixed-language teams-
nextjs-appWebNext.js, SSR, ReactDefault consumer web or full-stack appConsumer example
react-spaWebVite, React, SPAConsole / internal app / no SEOAdmin example
astro-siteWebAstro, static-firstMarketing or content siteMarketing example
starlight-docsDocsStarlight, AstroDocumentation site or knowledge baseDocs example
expo-mobileMobileExpo, React NativeCross-platform iOS + AndroidMobile example
electron-appDesktopElectron, React, ViteDesktop app for macOS / Windows / LinuxDesktop example
ts-libraryLibraryTS, strict semverReusable TypeScript package-
go-libLibraryGo, module, package layoutReusable Go module-

Add The Template You Chose

The ID column is the first argument after one add.

If you are still unsure, use the interactive flow:

one add

If you already picked a template:

one templates
one add nestjs-api --name api

nestjs-api comes from the template ID. api is the project name you choose.

Full-stack SaaS (default)

one create my-saas
cd my-saas
one add nestjs-api --name api
one add nextjs-app --name web
one add ts-library --name shared

Why: TypeScript across the stack lets shared be used by both API and web. Next.js can cover SEO and authenticated app surfaces.

High-performance Backend + Static Marketing

one add go-api --name api
one add astro-site --name marketing
one add react-spa --name console

Why: Go handles traffic; Astro keeps the public site fast and SEO-friendly; React SPA works for an authenticated console.

Mobile + API

one add nestjs-api --name api
one add expo-mobile --name app
one add ts-library --name shared

shared can hold DTOs and business types reused by React Native and the API.

Still Unsure?

Run one templates -o json for full template metadata, or run one add interactively. The picker includes category and one-line descriptions.

You can also pick one of the recommended combos above, get it running, and change course once you know more.

Template dependencies and Electron workspaces

Node templates do not copy pre-generated lockfiles. one dev creates or updates the repository's root lockfile when needed; commit it to Git. one build validates an existing lockfile without rewriting it.

electron-app requires a pnpm workspace. It remains one One project, while its main, UI, and preload packages join the root pnpm-workspace.yaml and share the root lockfile. Package names use the project name as their scope, for example @desktop/electron, @desktop/ui, and @desktop/preload, so multiple desktop apps can coexist.

The template follows the root package-manager version, registry, and mirror settings. Existing build-script policies are preserved; configurations without a policy receive the bundled template defaults. Explicit denials of Electron's installation script must be adjusted at the root. For concurrent desktop development, set a different ELECTRON_RENDERER_PORT in each project's environment.

These rules apply to newly generated projects. Existing Electron projects are not automatically rewritten or migrated.

Develop directly in a template directory

Bundled templates contain ordinary source files that you can run and debug in packages/templates/<id>. Go templates have a local go.work to isolate them from the repository workspace. Electron has a pnpm-workspace.yaml for template development. These development files are excluded from generated projects, which use the destination One workspace's configuration.

For example, inside the One CLI source repository:

cd packages/templates/go-api
go test ./...
go run ./cmd/server

The Go API defaults to in-memory SQLite. Configure environment variables as described by the template when using PostgreSQL or other runtime settings.

cd packages/templates/electron-app
pnpm install
pnpm run dev

Electron builds preload first, then starts the main process and Vite UI. The host still needs Electron's graphical environment and system sandbox support. Use pnpm run build for a build without launching the application.

For a single-package Node template such as React, isolate the parent workspace:

cd packages/templates/react-spa
pnpm --ignore-workspace install
pnpm --ignore-workspace run dev

Template development uses the pnpm version in its package.json. Generated projects inherit the destination workspace's version. Local dependencies, lockfiles and build artifacts are excluded from the CLI bundle.

Configure template generation

Files are copied verbatim by default. Only starters needing parameterization include a template.json file, with these supported settings:

SettingPurpose
schemaVersion: 1Declare the descriptor version
go.modulePrefixSet the generated module path and rewrite its Go imports
node.scope, node.sourceFilesRename internal Node packages, dependency keys, scripts and the scope in listed source files
textReplace example text in explicitly listed files
excludeExclude files or directories used only for template development

Each text rule contains files, from and value. The supported values are projectName and projectNameKebabCase. Optional minMatches defaults to 1; every listed file must meet that count. Paths are exact, template-relative paths. No scripts or expressions are executed. Unknown fields, missing files, insufficient matches and overlapping replacements fail before destination writes.

Go templates maintain one normal go.mod and a go.sum when needed. Bundling temporarily renames go.mod to _go.mod to avoid Go's nested-module embedding restriction; generation restores the filename. Do not edit the generated resources in packages/cli/internal/resources/bundled/ manually.

After editing, run these commands from the repository root:

mise run sync-bundled
mise run check
mise run check:templates

check:templates installs the Electron template dependencies, builds the Go and Electron sources, checks generated formatting for every Node template, and builds two differently named Electron projects plus two Go projects in a temporary workspace. It requires network access and the corresponding toolchains, and does not change the developer's global language preference.