Agent-native code generation for TanStack Start and any framework that speaks the Protocol.
tsx run add-feature --json '{"name":"products","fields":[{"name":"title","type":"string"}]}'
# → db/schema/products.ts
# → server-functions/products.ts
# → hooks/use-products.ts
# → components/ProductsForm.tsx
# → components/ProductsTable.tsx
# → routes/products/index.tsx
# → routes/products/$id.tsxtsx is a Rust CLI that eliminates boilerplate for AI agents building TanStack Start applications. Instead of an agent spending 300–800 tokens writing each file from scratch, it calls a single CLI command and receives fully-wired, production-ready files on disk.
The key shift in v6 is that tsx becomes a Universal Framework Protocol — any framework author can publish a tsx-compatible package that gives agents instant, token-efficient access to their framework's knowledge and code generation.
Without tsx (agent writes files directly):
generate schema → ~600 tokens
generate server fn → ~500 tokens
generate query → ~400 tokens
generate form → ~700 tokens
generate table → ~600 tokens
total per feature → ~2,800 tokens
With tsx:
tsx describe tanstack-start → ~80 tokens (discover what's available)
tsx ask "how to add auth" → ~120 tokens (specific answer)
tsx run add-feature --json '{...}' → 0 tokens (file written to disk)
total per feature → ~200 tokens
80–95% token reduction per typical scaffolding task.
cargo install tsxOr build from source:
git clone https://github.com/ateeq1999/tsx.git
cd tsx
cargo build --release
# binary: target/release/tsx.exe (Windows) or target/release/tsxRequirements: Rust 1.70+. No Node.js, no npm, no runtime dependencies — single statically-linked binary (~11 MB).
# 1. Scaffold a new project from a starter recipe
tsx create --from tanstack-start --starter basic
# 2. Generate a complete CRUD feature
tsx run add-feature --json '{"name":"products","fields":[{"name":"title","type":"string"},{"name":"price","type":"number"}]}'
# 3. Apply the migration
tsx add migration
# 4. List what else you can generate
tsx run --listRun any generator defined by any installed framework. Validates your JSON input against the generator's schema before executing.
# List all available generators
tsx run --list
tsx run --list --fw tanstack-start
# Run a generator (by id or command name — both work)
tsx run add-schema --json '{"name":"users","fields":[{"name":"email","type":"string"}]}'
tsx run add:schema --json '{"name":"users","fields":[{"name":"email","type":"string"}]}'
# Preview output paths without writing files
tsx run add-feature --json '{"name":"orders"}' --dry-run
# Pipe JSON from stdin
echo '{"name":"orders"}' | tsx run add-feature --stdin
# Read JSON from a file
tsx run add-feature --file feature.jsonThe response includes next_steps — the generator tells you what to run next:
{
"success": true,
"command": "run",
"result": {
"id": "add-feature",
"framework": "tanstack-start",
"files_created": ["db/schema/orders.ts", "server-functions/orders.ts", "..."],
"next_steps": [
"Run `tsx add migration` to apply the schema",
"Add <Link to=\"/orders\" /> to your navigation"
]
},
"metadata": { "duration_ms": 42 }
}| Generator | Alias | Output |
|---|---|---|
add-schema |
add:schema |
db/schema/<name>.ts — Drizzle ORM table definition |
add-server-fn |
add:server-fn |
server-functions/<name>.ts — typed server function |
add-query |
add:query |
hooks/use-<name>.ts — TanStack Query hook |
add-form |
add:form |
components/<name>Form.tsx — TanStack Form component |
add-table |
add:table |
components/<name>Table.tsx — TanStack Table component |
add-page |
add:page |
routes/<path>/index.tsx — route page |
add-seed |
add:seed |
db/seed/<name>.ts — Drizzle seed file |
add-feature |
add:feature |
All 7 files above in one command |
Every generator declares its input schema (subset of JSON Schema). tsx run validates your input and fills defaults before executing — bad input is rejected with a clear error, not a crash.
{
"name": "users",
"fields": [
{ "name": "email", "type": "string", "unique": true },
{ "name": "role", "type": "string" }
],
"timestamps": true,
"soft_delete": false
}{
"name": "getUser",
"method": "GET",
"auth": true,
"return_type": "User"
}{
"name": "user",
"operations": ["list", "get", "create", "update", "delete"]
}{
"name": "User",
"fields": [
{ "name": "email", "type": "email", "required": true },
{ "name": "role", "type": "select" }
],
"submit_label": "Save"
}{
"name": "User",
"columns": [
{ "key": "email", "label": "Email", "sortable": true },
{ "key": "role", "label": "Role" }
],
"searchable": true,
"pagination": true
}{
"path": "dashboard",
"auth": true,
"loader": false
}{
"name": "users",
"count": 20
}{
"name": "products",
"fields": [
{ "name": "title", "type": "string", "required": true },
{ "name": "price", "type": "number" },
{ "name": "active", "type": "boolean" }
],
"timestamps": true,
"auth": false
}These are stable aliases for the most common generators. They accept the same --json / --stdin / --file flags.
tsx generate schema --json '{"name":"users",...}'
tsx generate server-fn --json '{"name":"getUser",...}'
tsx generate query --json '{"name":"user",...}'
tsx generate form --json '{"name":"User",...}'
tsx generate table --json '{"name":"User",...}'
tsx generate page --json '{"path":"dashboard",...}'
tsx generate seed --json '{"name":"users",...}'
tsx generate feature --json '{"name":"products",...}'
tsx add auth --json '{"providers":["github","google"]}'
tsx add auth-guard --json '{"route_path":"/dashboard","redirect_to":"/login"}'
tsx add migrationScaffold a full project from a starter recipe.
tsx create --from tanstack-start # built-in basic starter
tsx create --from tanstack-start --starter with-auth # starter with Better Auth
tsx create --from tanstack-start --starter saas # SaaS starter
tsx create --from @tsx-pkg/tanstack-start # from npm package
tsx create --from github:user/my-tsx-pkg # from GitHub repo
tsx create --from tanstack-start --dry-run # preview steps onlyAvailable starters for tanstack-start: basic, with-auth, saas.
tsx is a conversation partner for any installed framework — not just a code generator.
Agent entry point. Returns what knowledge is available and its token cost before committing to loading anything.
tsx describe tanstack-start
tsx describe tanstack-start --section overview
tsx describe tanstack-start --section faq{
"framework": "TanStack Start",
"version": "1.0.0",
"available_knowledge": {
"overview": { "token_estimate": 150, "cmd": "tsx describe tanstack-start --section overview" },
"concepts": { "token_estimate": 400, "cmd": "tsx describe tanstack-start --section concepts" },
"patterns": { "token_estimate": 600 },
"faq_topics": 28
},
"generators": 8,
"starters": ["basic", "with-auth", "saas"],
"quick_start": "tsx create --from tanstack-start --starter basic"
}Answer questions about a framework. Framework is auto-detected from package.json when omitted.
tsx ask --question "How do I add authentication?"
tsx ask --question "How do I add authentication?" --framework tanstack-start
tsx ask --question "How do I add authentication?" --framework tanstack-start --depth brief
tsx ask --question "How do I add authentication?" --framework tanstack-start --depth full--depth values: brief (~50 tokens), default (~150 tokens), full (~400 tokens).
Find where things live in a framework.
tsx where --thing schema
tsx where --thing "route page" --framework tanstack-startGet integration steps for a package.
tsx how --integration "@tanstack/react-router"
tsx how --integration better-auth --framework tanstack-startExplain template decisions and architecture.
tsx explain --topic atom
tsx explain --topic "why tera over minijinja"tsx framework init --name my-framework # scaffold a new framework package
tsx framework validate # lint manifest + templates in cwd
tsx framework validate --path ./my-pkg # lint a specific path
tsx framework preview --template auth.forge --data '{"name":"users"}'
tsx framework add ./my-pkg # install from local path
tsx framework add @tsx-pkg/stripe # install from npm
tsx framework list # list installed packages
tsx framework publish # publish to npm as @tsx-pkg/<id>
tsx framework publish --dry-run # validate without uploadingExecute multiple generators in a single call with rollback support.
tsx batch --json '{
"stop_on_failure": true,
"rollback_on_failure": true,
"commands": [
{ "command": "add:schema", "options": {"name":"orders","fields":[...]} },
{ "command": "add:server-fn", "options": {"name":"getOrders"} },
{ "command": "add:query", "options": {"name":"order"} }
]
}'Supports --stream to emit each result as newline-delimited JSON as it completes.
Scan the current project and return its structure, detected framework, auth config, and migration status.
tsx inspect
tsx inspect --verbosetsx list --kind templates
tsx list --kind generators
tsx list --kind frameworks
tsx list --kind componentsStart the development server with optional JSON event streaming and WebSocket support.
tsx dev
tsx dev --json-events # emit structured JSON events to stdout
tsx dev --watch # regenerate on template changes
tsx dev --ws-port 7332 # WebSocket server for IDE integrationStart a Server-Sent Events server for external tool integration.
tsx subscribe --port 7331tsx plugin list
tsx plugin install --source ./my-plugin
tsx plugin install --source @my-org/tsx-plugin-stripe
tsx plugin remove --package @my-org/tsx-plugin-stripe| Flag | Description |
|---|---|
--overwrite |
Overwrite existing files without prompting |
--dry-run |
Preview what would be written without creating files |
--verbose |
Include project root, tsx version, and extended context in response |
--stdin |
Read JSON payload from stdin |
--file <PATH> |
Read JSON payload from a file |
All commands return a consistent JSON envelope — designed for AI agent consumption.
{
"success": true,
"version": "1.0",
"command": "run",
"result": {
"id": "add-feature",
"framework": "tanstack-start",
"files_created": ["db/schema/products.ts", "..."],
"next_steps": ["Run `tsx add migration`"]
},
"metadata": {
"timestamp": "2026-03-16T10:00:00Z",
"duration_ms": 38
}
}{
"success": false,
"command": "run",
"error": {
"code": "VALIDATION_ERROR",
"message": "missing required field 'name'"
},
"metadata": { "duration_ms": 1 }
}| Code | Meaning |
|---|---|
INVALID_PAYLOAD |
JSON payload is malformed |
VALIDATION_ERROR |
Input fails schema validation |
UNKNOWN_COMMAND |
Generator ID not found in any installed framework |
UNKNOWN_KIND |
--kind value not recognised by tsx list |
FILE_EXISTS |
Target file exists and --overwrite was not set |
DIRECTORY_NOT_FOUND |
Required parent directory does not exist |
PERMISSION_DENIED |
Cannot write to target location |
TEMPLATE_NOT_FOUND |
Generator template file missing |
PROJECT_NOT_FOUND |
No package.json found — run from a project directory |
INTERNAL_ERROR |
Unexpected error in the CLI |
Framework authors publish tsx-compatible packages to npm as @tsx-pkg/<name>. Once installed with tsx framework add @tsx-pkg/<name>, all generators become available via tsx run.
@tsx-pkg/tanstack-start/
manifest.json ← package identity, generators, starters
knowledge/
overview.md ← what this framework is (≤ 150 tokens)
concepts.md ← key terms + glossary (≤ 400 tokens)
patterns.md ← common patterns with snippets (≤ 600 tokens)
faq.md ← Q&A pairs (frontmatter-structured)
decisions.md ← design rationale (≤ 500 tokens)
generators/
add-schema.json ← generator spec (id + command + schema + output_paths)
add-feature.json
...
templates/
atoms/ ← indivisible code fragments (.forge files)
molecules/ ← composed blocks
layouts/ ← file-level shells
features/ ← full output templates
starters/
basic.json ← ordered command steps
with-auth.json
integrations/
better-auth.json ← integration pattern
drizzle-orm.json
{
"id": "tanstack-start",
"name": "TanStack Start",
"version": "1.0.0",
"category": "framework",
"description": "Full-stack React meta-framework",
"docs": "https://tanstack.com/start",
"peer_dependencies": {
"@tanstack/start": "^1.0",
"@tanstack/react-router": "^1.0"
},
"knowledge_token_budget": {
"overview": 150,
"concepts": 400,
"patterns": 600,
"faq_per_entry": 120
},
"generators": ["add-schema", "add-server-fn", "add-query", "add-form", "add-table", "add-page", "add-seed", "add-feature"],
"starters": ["basic", "with-auth", "saas"],
"templates_dir": "templates",
"template_format": "forge"
}{
"id": "add-schema",
"command": "add:schema",
"description": "Generate a Drizzle ORM schema table definition",
"token_estimate": 30,
"output_paths": ["db/schema/{{name}}.ts"],
"next_steps": [
"Run `tsx add migration` to apply the schema to your database"
],
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "description": "Table name (snake_case)" },
"timestamps": { "type": "boolean", "default": true },
"soft_delete": { "type": "boolean", "default": false }
}
}
}---
id: add-auth
question: How do I add authentication?
tags: [auth, security, setup]
token_estimate: 120
requires: [better-auth]
related: [add-migration, add-auth-guard]
---
## Adding Authentication
Run `tsx add auth` to scaffold Better Auth. This creates `lib/auth.ts`...{# forge:tier atom #}
{# forge:token_estimate 12 #}
{% if field.type == "string" %}
{{ field.name | snake_case }}: text('{{ field.name }}'){{ collect_import("text", "drizzle-orm/sqlite-core") }},
{% elif field.type == "number" %}
{{ field.name | snake_case }}: integer('{{ field.name }}'){{ collect_import("integer", "drizzle-orm/sqlite-core") }},
{% endif %}Built-in forge filters: collect_import, snake_case, pascal_case, camel_case, kebab_case.
Built-in forge functions: render_imports() — drains the ImportCollector at the file top.
{
"id": "with-auth",
"name": "With Auth Starter",
"description": "TanStack Start with Better Auth pre-configured",
"token_estimate": 40,
"steps": [
{ "cmd": "init", "args": {} },
{ "cmd": "add:auth", "args": { "providers": ["email"] } },
{ "cmd": "add:schema", "args": { "name": "users", "timestamps": true } },
{ "cmd": "add:migration","args": {} }
]
}tsx/
├── src/
│ ├── main.rs ← clap CLI definition + dispatch
│ ├── commands/
│ │ ├── generate/ ← add_schema, add_feature, etc. (compiled-in)
│ │ ├── manage/ ← create, framework_cmd, init, dev
│ │ ├── ops/
│ │ │ ├── batch.rs ← batch executor + execute_command_pub
│ │ │ ├── run.rs ← universal dispatcher (tsx run)
│ │ │ └── generate.rs ← framework generator runner
│ │ └── query/ ← ask, describe, where, how, explain
│ ├── framework/
│ │ ├── command_registry.rs ← scans generators/ dirs, validates input
│ │ ├── loader.rs ← loads manifest.json + registry.json formats
│ │ ├── detect.rs ← auto-detects framework from package.json
│ │ ├── knowledge.rs ← markdown frontmatter parser
│ │ ├── token_budget.rs ← depth system (brief/default/full)
│ │ └── package_cache.rs ← .tsx/frameworks/packages.json tracking
│ ├── schemas/ ← serde structs for all command payloads
│ ├── render/ ← MiniJinja engine + ImportCollector
│ ├── utils/ ← paths, write, imports, barrel, format
│ └── json/ ← payload, response, error types
├── crates/forge/ ← the forge engine crate (published as tsx-forge)
│ └── src/
│ ├── engine.rs ← Tera wrapper with tier awareness
│ ├── collector.rs ← ImportCollector (thread-local BTreeSet)
│ ├── tier.rs ← Atom/Molecule/Layout/Feature types
│ ├── context.rs ← ForgeContext builder with provide/inject + slots
│ ├── slots.rs ← Component slot system (thread-local)
│ ├── provide.rs ← Provide/Inject context propagation (thread-local)
│ └── metadata.rs ← token_estimate frontmatter reader
├── frameworks/
│ └── tanstack-start/ ← built-in reference implementation
│ ├── manifest.json
│ ├── knowledge/ ← overview, concepts, patterns, faq, decisions
│ ├── generators/ ← 8 generator specs (JSON Schema + output_paths)
│ ├── templates/ ← 33 .forge templates (atoms/molecules/layouts/features)
│ ├── starters/ ← basic, with-auth, saas recipes
│ └── integrations/ ← better-auth, drizzle-orm, shadcn-ui, etc.
└── templates/ ← compiled-in MiniJinja templates (embedded in binary)
├── atoms/
├── molecules/
├── layouts/
└── features/
Code generation is powered by the forge crate (built on Tera). Templates are composed in four tiers:
| Tier | Role | Jinja2 primitive |
|---|---|---|
| Atoms | Indivisible code fragments (a single column definition, a single Zod rule) | {% include %} |
| Molecules | Atoms composed into logical blocks (a full table body, a form component) | {% macro %} / {{ caller() }} |
| Layouts | File-level shells that emit imports at the top and wrap molecules | {% extends %} + {% block %} |
| Features | Complete output templates that wire molecules into layouts | Top-level template |
ImportCollector — imports are accumulated via {{ collect_import("text", "drizzle-orm/sqlite-core") }} deep inside atoms, then drained and emitted as a deduplicated, sorted block at the file top via {{ render_imports() }} in the layout. This ensures every generated file has correct imports regardless of which atoms were included.
Component slots — layouts declare {{ slot(name='body') }} placeholders; feature templates fill them with .slot("body", content) on ForgeContext.
Provide/Inject — parent contexts make values available via .provide("theme", "dark"); any descendant template reads them with {{ inject(key='theme') }}.
At startup, tsx run instantiates CommandRegistry::load_all() which:
- Scans
<exe_dir>/frameworks/(built-in, shipped with the binary) - Scans
<cwd>/.tsx/frameworks/(user-installed packages) - Reads every
generators/<id>.jsonfrom each framework directory - Resolves by
id("add-schema") orcommand("add:schema") — both work
This means adding a new generator to any installed framework package requires zero Rust code — just drop a JSON file.
cargo build # debug build
cargo build --release # production build (LTO, stripped, ~11 MB)cargo test # all tests
cargo test --lib # unit tests only
cargo test -p tsx-forge # forge crate testscargo bench --bench render_bench -p tsx-forgeBenchmarks compare forge (Tera-based) vs MiniJinja on the full atom → molecule → layout → feature pipeline.
- Command handlers live in
src/commands/— one module per logical group - All commands return
CommandResultand print aResponseEnvelope— nevereprintln! - New generators for
tanstack-startgo inframeworks/tanstack-start/generators/<id>.json— no Rust required - New compiled-in commands need a handler in
src/commands/, a schema insrc/schemas/, a dispatch arm insrc/main.rs, and registration insrc/commands/ops/batch.rs'sexecute_command()
| Crate | Role |
|---|---|
clap v4 |
Argument parsing and subcommand routing |
tsx-forge |
4-tier code generation engine (Tera-based) |
minijinja |
Template engine for compiled-in templates |
serde + serde_json |
JSON payload deserialisation and structured output |
anyhow |
Error propagation |
walkdir |
Project root auto-detection |
heck |
Case conversion (snake_case, PascalCase, camelCase) |
reqwest + tokio |
npm package fetching |
notify |
File system watcher (dev mode) |
tungstenite |
WebSocket server (dev mode) |
| Technology | Role |
|---|---|
| TanStack Start | Full-stack React meta-framework |
| TanStack Router | Type-safe file-based routing |
| TanStack Query | Server state and caching |
| TanStack Form | Type-safe form handling |
| TanStack Table | Headless data tables |
| shadcn/ui | Accessible component library |
| Better Auth | Authentication |
| Drizzle ORM | Type-safe SQL query builder |
| Tailwind CSS | Utility-first CSS |
MIT — see LICENSE.