Skip to main content

adding-templates

Use when adding new stacks, libraries, or project addons to create-faster CLI tool - covers META entries, template creation, and testing for all addon types

Source facts

Repository
plvo/create-faster
Last source activity
February 11, 2026 at 11:35
Detected SKILL.md language
English
Stars
28
Forks
1

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
adding-templates
description
Use when adding new stacks, libraries, or project addons to create-faster CLI tool - covers META entries, template creation, and testing for all addon types
# Adding Templates to create-faster ## Overview Add new content to the create-faster CLI: framework stacks, per-app libraries, or project-level addons. All additions are data-driven through META configuration + Handlebars templates. **Core principle:** Understand-first, copy-second. Know the library/framework BEFORE writing templates. ## When to Use Use this skill when: - Adding a new framework stack (Remix, Astro, SvelteKit, etc.) - Adding a new library (tRPC, i18n, Storybook, etc.) - Adding a new project addon (new database, ORM, tooling) Do NOT use for: - Fixing existing templates (use `fixing-templates` skill) - Extracting a library from an external project (use `extracting-templates` skill first, then come here) - Updating dependency versions ## Architecture Context Adding content is **data-driven**. Most CLI code operates generically on META configuration. Only source files that define types need changes. Everything else is META entries + template files. **What does NOT change** when adding content (17+ files are generic): - `cli.ts`, `flags.ts`, `index.ts` — iterate META entries - `template-resolver.ts` — scans template directories by convention - `package-json-generator.ts` — merges from `META.*.packageJson` - `env-generator.ts` — collects envs from META - `handlebars.ts` — generic helpers - `addon-utils.ts` — generic compatibility checks - All prompts, TUI, summary code ### Three Addon Types | Type | META location | Template directory | Scope | |------|--------------|-------------------|-------| | Stack | `META.stacks` | `templates/stack/{name}/` | Per-app | | Library | `META.libraries` | `templates/libraries/{name}/` | Per-app | | Project addon | `META.project.{category}.options` | `templates/project/{category}/{name}/` | Project-level | ## Adding a Stack ### Source Changes **Only 2-3 source files need code changes:** #### a. Add to `StackName` union (`types/meta.ts`) ```typescript export type StackName = 'nextjs' | 'expo' | 'hono' | 'tanstack-start' | 'newstack'; ``` All downstream types derive from `StackName` automatically. #### b. Add stack entry to META (`__meta__.ts`) ```typescript newstack: { type: 'app' | 'server', label: 'Framework Name', hint: 'Short description', packageJson: { dependencies: { 'framework-core': '^1.0.0' }, devDependencies: { typescript: '^5' }, scripts: { dev: 'framework dev --port {{port}}', build: 'framework build', start: 'framework start --port {{port}}', }, }, }, ``` **Scripts with `{{port}}`:** `package-json-generator.ts` resolves placeholders: - Turborepo: `{{port}}` → `3000 + appIndex` - Single repo: the `--port {{port}}` portion is stripped entirely #### c. Add file extensions to KNOWN_EXTENSIONS (if needed, `lib/frontmatter.ts`) Non-standard extensions (`.svelte`, `.vue`, `.astro`) prevent the stack suffix parser from misidentifying them. ### Template Structure ``` templates/stack/{stackname}/ {config}.config.ts.hbs # Vite, Next, etc. tsconfig.json.hbs # TypeScript config src/ {entry-point}.tsx.hbs # Main entry routes/ # Routing (if file-based) components/ # Shared components public/ # Static assets (if needed) ``` ### Library Compatibility Check existing libraries with `support: { stacks: 'all' }`. React libraries shouldn't be available for non-React stacks — change to explicit list: ```typescript support: { stacks: ['nextjs', 'tanstack-start'] }, // React-only ``` ## Adding a Library ### META Entry (`META.libraries`) ```typescript newlib: { label: 'Library Name', hint: 'Short description', category: 'UI', // Groups in interactive prompt (UI, Content, Auth, API, Data Fetching, Forms, Deploy) support: { stacks: ['nextjs', 'tanstack-start'] }, // Optional: require other addons require: { orm: ['drizzle', 'prisma'] }, // Optional: turborepo shared package mono: { scope: 'pkg', name: 'libname' }, packageJson: { dependencies: { 'the-lib': '^1.0.0' }, // Optional: package exports (for shared packages) exports: { '.': './src/index.ts' }, }, // Optional: environment variables envs: [ { value: 'LIB_SECRET=changeme', monoScope: [{ pkg: 'libname' }, 'app'] }, ], }, ``` **Key fields:** - `category` — prompt group name (UI, Content, Auth, API, Data Fetching, Forms, Deploy) - `support.stacks` — which stacks can use this library (`'all'` or explicit list) - `require` — dependencies on other addons (e.g., better-auth requires orm) - `mono` — if set, library gets its own `packages/{name}/` in turborepo - `envs` — env vars with scope resolution (which `.env.example` files get them) ### Template Structure ``` templates/libraries/{libname}/ src/lib/{feature}.ts.hbs # Library setup files src/lib/{feature}-client.ts.hbs # Client-side setup src/app/api/{route}/route.ts.nextjs.hbs # Stack-specific API routes ``` ### Handlebars Conditionals for Cross-Library Integration When a library's behavior changes based on OTHER selected libraries: ```handlebars {{!-- In the library's own template --}} {{#if (hasLibrary "other-lib")}} import { something } from '{{#if (isMono)}}@repo/other{{else}}@/lib/other{{/if}}'; {{/if}} {{!-- Conditional feature based on project addon --}} {{#if (has "orm" "drizzle")}} import { db } from '{{#if (isMono)}}@repo/db{{else}}@/lib/db{{/if}}'; {{/if}} ``` ### Modifying Existing Templates Libraries often need to modify existing stack templates (e.g., `app-providers.tsx.hbs`): ```handlebars {{!-- Add import --}} {{#if (hasLibrary "newlib")}} import { NewLibProvider } from '@/lib/newlib'; {{/if}} {{!-- Add provider wrapper --}} {{#if (hasLibrary "newlib")}} <NewLibProvider> {{/if}} {children} {{#if (hasLibrary "newlib")}} </NewLibProvider> {{/if}} ``` **Wrap order matters** — check existing conditionals and add in the right position. ## Adding a Project Addon ### META Entry (`META.project.{category}.options`) ```typescript // In META.project.{category}.options: newoption: { label: 'Option Name', hint: 'Short description', mono: { scope: 'root' }, // or { scope: 'pkg', name: 'pkgname' } packageJson: { dependencies: { 'the-pkg': '^1.0.0' }, scripts: { 'task:run': 'the-pkg run' }, }, envs: [ { value: 'DB_URL="connection-string"', monoScope: [{ pkg: 'db' }, 'app'] }, ], }, ``` ### Template Structure ``` templates/project/{category}/{name}/ config-file.ts.hbs scripts/seed.ts.hbs ``` ## Programmatic Files — NO Templates **package.json** — generated from META `packageJson`. No `package.json.hbs`. **.env.example** — generated from META `envs`. No `.env.example.hbs`. ## Template Authoring Reference ### YAML Frontmatter ```yaml --- path: src/lib/feature.ts # Output path (single repo) mono: scope: app | pkg | root # Monorepo scope (overrides META) path: src/feature.ts # Monorepo path (relative to scope) only: mono | single # Repo type filter --- ``` ### Stack-Specific File Suffix `file.ext.{stack}.hbs` — only included when app uses that stack: ``` route.ts.nextjs.hbs → only for Next.js apps adapter.ts.hono.hbs → only for Hono apps ``` ### Available Handlebars Helpers | Helper | Purpose | |--------|---------| | `isMono` | Check if turborepo | | `hasLibrary "name"` | Check if current app has library | | `has "category" "value"` | Check database/orm/tooling/stack | | `hasContext "key"` | Check if key exists in context | | `appPort appName` | Get port for app (3000 + index) | | `eq`, `ne`, `and`, `or` | Logical operators | ### Special Filename Handling - `__filename` → `.filename` (dotfiles like `.gitignore`) - `___filename` → `__filename` (literal double underscore) ## Testing **DO NOT assume templates work. Verify.** 1. Single repo mode: ```bash bunx create-faster test-single --app test-single:{stack}:{lib1},{lib2} ``` 2. Turborepo mode: ```bash bunx create-faster test-turbo --app web:{stack}:{lib1},{lib2} --app api:hono ``` 3. Verify: - All template files present in output - `package.json` has correct dependencies - Conditional code renders correctly for all combinations - `bun install && bun run dev` works 4. Test all library combinations that affect templates: - Library alone - Library + each cross-library integration - Library in single vs turborepo mode ## Checklist ### Stack - [ ] Added to `StackName` union in `types/meta.ts` - [ ] Added META entry with `packageJson` (deps + scripts) - [ ] Added file extension to `KNOWN_EXTENSIONS` (if applicable) - [ ] Created `templates/stack/{name}/` with all source files - [ ] Checked library compatibility (`stacks: 'all'` audit) - [ ] Tested single + turborepo mode - [ ] Verified dev/build works ### Library - [ ] Added META entry in `META.libraries` with category/support/require/mono/packageJson/envs - [ ] Created `templates/libraries/{name}/` with template files - [ ] Modified existing stack templates for cross-library conditionals - [ ] Used stack-specific suffix where needed (`.nextjs.hbs`) - [ ] Tested all library combinations - [ ] Tested single + turborepo mode ### Project Addon - [ ] Added META entry in `META.project.{category}.options` - [ ] Created `templates/project/{category}/{name}/` - [ ] Tested with different stack/library combinations ## Common Rationalizations — STOP | Excuse | Reality | |--------|---------| | "I need a package.json.hbs" | Package.json is programmatic from META. No template. | | "I need a .env.example.hbs" | Env files are programmatic from META `envs`. No template. | | "I'll skip testing combinations" | Library combinations produce different output. Test them. | | "Close enough, it'll probably work" | Probably = broken. Test it. | | "I can skip the monorepo test" | Single and turborepo produce different paths. Test both. | | "I'll use magic comments" | Removed. Use YAML frontmatter. | ## Quick Reference | What | Where | How | |------|-------|-----| | Stack definition | `META.stacks` | `type`, `label`, `hint`, `packageJson` |
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub