Awesome-omni-skill 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
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/tools/adding-templates" ~/.claude/skills/diegosouzapw-awesome-omni-skill-adding-templates && rm -rf "$T"
skills/tools/adding-templates/SKILL.mdAdding 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
skill)fixing-templates - Extracting a library from an external project (use
skill first, then come here)extracting-templates - 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
— iterate META entriesindex.ts
— scans template directories by conventiontemplate-resolver.ts
— merges frompackage-json-generator.tsMETA.*.packageJson
— collects envs from METAenv-generator.ts
— generic helpershandlebars.ts
— generic compatibility checksaddon-utils.ts- All prompts, TUI, summary code
Three Addon Types
| Type | META location | Template directory | Scope |
|---|---|---|---|
| Stack | | | Per-app |
| Library | | | Per-app |
| Project addon | | | Project-level |
Adding a Stack
Source Changes
Only 2-3 source files need code changes:
a. Add to StackName
union (types/meta.ts
)
StackNametypes/meta.tsexport type StackName = 'nextjs' | 'expo' | 'hono' | 'tanstack-start' | 'newstack';
All downstream types derive from
StackName automatically.
b. Add stack entry to META (__meta__.ts
)
__meta__.tsnewstack: { 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
portion is stripped entirely--port {{port}}
c. Add file extensions to KNOWN_EXTENSIONS (if needed, lib/frontmatter.ts
)
lib/frontmatter.tsNon-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:
support: { stacks: ['nextjs', 'tanstack-start'] }, // React-only
Adding a Library
META Entry (META.libraries
)
META.librariesnewlib: { 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:
— prompt group name (UI, Content, Auth, API, Data Fetching, Forms, Deploy)category
— which stacks can use this library (support.stacks
or explicit list)'all'
— dependencies on other addons (e.g., better-auth requires orm)require
— if set, library gets its ownmono
in turborepopackages/{name}/
— env vars with scope resolution (whichenvs
files get them).env.example
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:
{{!-- 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):
{{!-- 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
)
META.project.{category}.options// 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
--- 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 |
|---|---|
| Check if turborepo |
| Check if current app has library |
| Check database/orm/tooling/stack |
| Check if key exists in context |
| Get port for app (3000 + index) |
, , , | Logical operators |
Special Filename Handling
→__filename
(dotfiles like.filename
).gitignore
→___filename
(literal double underscore)__filename
Testing
DO NOT assume templates work. Verify.
-
Single repo mode:
bunx create-faster test-single --app test-single:{stack}:{lib1},{lib2} -
Turborepo mode:
bunx create-faster test-turbo --app web:{stack}:{lib1},{lib2} --app api:hono -
Verify:
- All template files present in output
has correct dependenciespackage.json- Conditional code renders correctly for all combinations
worksbun install && bun run dev
-
Test all library combinations that affect templates:
- Library alone
- Library + each cross-library integration
- Library in single vs turborepo mode
Checklist
Stack
- Added to
union inStackNametypes/meta.ts - Added META entry with
(deps + scripts)packageJson - Added file extension to
(if applicable)KNOWN_EXTENSIONS - Created
with all source filestemplates/stack/{name}/ - Checked library compatibility (
audit)stacks: 'all' - Tested single + turborepo mode
- Verified dev/build works
Library
- Added META entry in
with category/support/require/mono/packageJson/envsMETA.libraries - Created
with template filestemplates/libraries/{name}/ - 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 . 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 | | , , , |
| Library definition | | , , , , , , , |
| Project addon | | , , , , |
| Type union | in | Add new literal |
| Stack templates | | files |
| Library templates | | files |
| Project templates | | files |
| Package.json | Programmatic | reads META |
| Env vars | Programmatic | reads META |
| File extensions | | |
| Frontmatter | YAML in | , , |
| Helpers | | , , , , |