CLI Docs
AI/LLM: This documentation page is available in plain markdown format at/cli/latest/docs/creating-add-ons.md
Authoring
Creating Add-ons
Add-ons add files, dependencies, and code hooks to generated projects.
Use this guide when you want to build and maintain your own add-on outside the built-in catalog.
Quick Start#
shell
# 1. Create base project
tanstack create my-addon-dev -y
# 2. Add your code
# - src/integrations/my-feature/
# - src/routes/demo/my-feature.tsx
# - Update package.json
# 3. Extract add-on
tanstack add-on init
# 4. Edit .add-on/info.json
# 5. Compile
tanstack add-on compile
# Optional: continuously rebuild while authoring
tanstack add-on dev
# 6. Test locally
npx serve .add-on -l 9080
tanstack create test --add-ons http://localhost:9080/info.jsonStructure#
plaintext
.add-on/
├── info.json # Metadata (required)
├── package.json # Dependencies (optional)
└── assets/ # Files to copy
└── src/
├── integrations/my-feature/
└── routes/demo/my-feature.tsxGenerated source of truth files in your project root:
- .add-on/info.json - add-on metadata and integration config
- .add-on/package.json - dependency/script additions merged into generated apps
- .add-on/assets/** - template files copied into target apps
info.json#
Required fields:
json
{
"name": "My Feature",
"version": "0.0.1",
"description": "What it does",
"type": "add-on",
"phase": "add-on",
"category": "tooling",
"modes": ["file-router"]
}| Field | Values |
|---|---|
| version | Semantic version for your add-on metadata (e.g. 0.0.1) |
| type | add-on, toolchain, deployment, example |
| phase | setup, add-on, example |
| category | tanstack, auth, database, orm, deploy, tooling, monitoring, api, i18n, cms, other |
Optional fields:
json
{
"dependsOn": ["tanstack-query"],
"conflicts": ["other-feature"],
"envVars": [{ "name": "API_KEY", "description": "...", "required": true }],
"gitignorePatterns": ["*.cache"]
}Hooks (Integrations)#
Inject code into generated projects:
json
{
"integrations": [
{
"type": "root-provider",
"jsName": "MyProvider",
"path": "src/integrations/my-feature/provider.tsx"
}
]
}| Type | Location | Use |
|---|---|---|
| root-provider | Wraps app in __root.tsx | Context providers |
| provider | Same, but simpler | Basic providers |
| vite-plugin | vite.config.ts | Vite plugins |
| devtools | After app in __root.tsx | Devtools |
| header-user | Header component | User menu, auth UI |
| layout | Layout wrapper | Dashboard layouts |
Demo Routes#
json
{
"routes": [
{
"url": "/demo/my-feature",
"name": "My Feature Demo",
"path": "src/routes/demo/my-feature.tsx",
"jsName": "MyFeatureDemo"
}
]
}Add-on Options#
Let users configure the add-on:
json
{
"options": {
"database": {
"type": "select",
"label": "Database",
"options": [
{ "value": "postgres", "label": "PostgreSQL" },
{ "value": "sqlite", "label": "SQLite" }
],
"default": "postgres"
}
}
}Access in EJS templates:
ejs
<% if (addOnOption['my-feature']?.database === 'postgres') { %>
// PostgreSQL code
<% } %>EJS Templates#
Files ending in .ejs are processed. Available variables:
| Variable | Type | Description |
|---|---|---|
| projectName | string | Project name |
| typescript | boolean | TS enabled |
| tailwind | boolean | Tailwind enabled |
| addOnEnabled | object | { [id]: boolean } |
| addOnOption | object | { [id]: options } |
File patterns:
| Pattern | Result |
|---|---|
| file.ts | Copied as-is |
| file.ts.ejs | EJS processed |
| _dot_gitignore | Becomes .gitignore |
| file.ts.append | Appended to existing |
Distribution#
Host on GitHub, npm, or any URL:
shell
tanstack create my-app --add-ons https://example.com/my-addon/info.jsonLocal Iteration Loop#
Fastest way to iterate on a custom add-on:
shell
# in your add-on project
tanstack add-on compile
npx serve .add-on -l 9080
# in another terminal
tanstack create test-app --add-ons http://localhost:9080/info.jsonIf you are actively editing templates, run tanstack add-on dev to auto-refresh .add-on and add-on.json on file changes.
Publishing Tips#
- Keep add-on source in git (not just compiled output).
- Re-run tanstack add-on compile after each metadata/template change.
- Publish .add-on contents to a stable URL.
- Prefer immutable/versioned URLs for production use.
Maintenance Checklist#
When you update a custom add-on:
- Update templates or metadata in your source project.
- Re-run tanstack add-on compile.
- Test with a clean scaffold (tanstack create ... --add-ons <url>).
- Verify install/build/lint in the generated app.
- Publish updated .add-on assets.
Troubleshooting#
- Add-on not found: Verify URL points directly to info.json.
- Template not applied: Ensure file is in .add-on/assets and ends with .ejs if templated.
- Option not taking effect: Confirm option key matches addOnOption['<id>'] usage in template.
- Integration code not injected: Check integrations[].type, jsName, and path in .add-on/info.json.