For the complete documentation index, see llms.txt. Prefer markdown by appending.mdto documentation URLs or sendingAccept: text/markdown.
AI-assisted development
Use Cursor, Claude Code, ChatGPT Codex, or Antigravity with Edge Kit. Rules, skills, and workflows for TanStack Start on Cloudflare Workers.
Edge Kit includes pre-configured rules, skills, a subagent, and a command for AI coding assistants. They teach the model the stack that actually ships: TanStack Start, Kumo, Oxlint, and Cloudflare bindings. Most models still default to Next.js, ESLint, and barrel imports, and these files correct that before the first edit.
Everything works out of the box with Cursor, Claude Code, ChatGPT Codex, Antigravity, and other tools that read AGENTS.md. Open the project and start coding.
Structure
AI configuration lives in a shared directory, with tool-specific folders pointing at it where a tool requires its own path:
The .agents/ directory holds the shared skills, commands, and agents. .claude/agents and .claude/commands are symlinks to those folders, so a new agent or command shows up in Claude as soon as you add the file. Each skill under .claude/skills/ is its own symlink. Cursor and other tools that follow the Agent Skills layout read .agents/skills/ and AGENTS.md from the repo root, so they do not need a second copy.
Cloud agents
.cursor/environment.json configures Cursor Cloud agents. When .env.local is missing, install.sh writes it from your Cursor secrets: auth, email, Turnstile, and the web analytics token. Add Stripe keys yourself if you need billing. The install does not require Wrangler or a Cloudflare login unless the task deploys. Prefer the existing dev terminal (pnpm dev on port 3000).
Rules
Rules are persistent instructions the model reads when it needs project-specific guidance: conventions, layout, and workflows it cannot infer from the file tree.
AGENTS.md
AGENTS.md at the project root is the primary rules file. It uses the format recognized by most AI coding tools. In Edge Kit it opens with the stack (TanStack Start, React 19, Kumo, Cloudflare Workers, a single package, Node 24 or newer) and then the things that break a build or a lint gate:
## Gotchas
**`@/*` is the only path alias.** `tsconfig.json` maps `@/*` to `./src/*`. There is no `#/*` alias.
**`env.config.ts` sits outside `src/`.** Import it by relative path, with the `.ts` extension.
**Two different things are called `env`.** Typed secrets come from `env.config.ts`. Cloudflare bindings come from `import { env } from "cloudflare:workers"`.
**`pnpm lint` is also the type check.** Oxlint is type-aware. There is no `typecheck` script.
**No literal strings in JSX.** `react/jsx-no-literals` is an error. User-facing copy goes through Paraglide.The rest of the file covers:
- Commands and the verify-before-you-finish sequence:
pnpm format:fix && pnpm lint && pnpm test. Runpnpm buildas well after route, SSR, or content-collection changes. - Layout. Infrastructure adapters live in
src/lib/, one product capability lives insrc/modules/<feature>/, andsrc/routes/only composes URLs. The billing module is the reference:*.server.tsfor D1,*.functions.tsforcreateServerFn,*.queries.tsfor TanStack Query. - Bindings. D1, KV, R2, Queue, Flagship, Workers AI, email, and rate limiting are declared in
wrangler.jsonc. Runpnpm cf-typegenafter you change them. Binding IDs never go inenv.config.ts. - Don'ts. No
#/imports, no Node-only APIs, no KV as durable state or as a flag store, no Sentry or other APM (usesrc/lib/log.ts), no business logic insrc/routes/, no hand-edited generated files (src/routeTree.gen.ts,worker-configuration.d.ts,src/lib/i18n/,.content-collections/,src/db/schema/auth.ts).
It also points models at version-pinned guidance inside node_modules: TanStack Start's skill, and Kumo's component registry plus USAGE.md. Kumo's own docs show a barrel import from @cloudflare/kumo. This repo imports by subpath (@cloudflare/kumo/components/button) so the Worker bundle stays small. The rules say to ignore the barrel example.
Rules should stay concise. Include only what the model cannot infer from code alone:
- Bash commands and the verify sequence
- Style rules that differ from defaults (Oxlint and Oxfmt, Paraglide, subpath imports)
- Layout decisions (modules vs
src/libvs routes) - Gotchas such as the two
envobjects
Keep rules short. Overly long files cause the model to ignore important instructions. If a rule is not being followed, the file might be too verbose.
CLAUDE.md
CLAUDE.md exists so Claude-specific tools load the same rules. It only references the main file:
@AGENTS.mdThat keeps one source of truth across tools.
Nested AGENTS.md files
You can nest AGENTS.md files in subdirectories when one area needs tighter rules. For example, src/modules/billing/ can document plan checks, and src/lib/auth/ can document session middleware.
The closer file generally wins for the code under it. Use nested files for domain rules, and keep shared conventions in the root file.
Provider-specific rules
Most tools also accept their own rules. Cursor rules go in .cursor/rules/. Claude rules go in .claude/.
If you primarily use one tool, add rules there when they should not apply to every assistant. Keep stack conventions in AGENTS.md so every tool sees them.
Skills
Skills are modular capabilities that extend the assistant with domain-specific knowledge. They package instructions and reference material that loads only when the task matches.
Skill structure
Each skill is a directory with a SKILL.md file, and optionally a references/ directory:
YAML frontmatter tells the tool when to apply the skill:
---
name: tanstack-start
description: Full-stack React framework built on TanStack Router. Use when building with SSR, server functions, middleware, or Cloudflare Workers deployment.
---
# TanStack Start
...The model reads description to decide when to load the skill. When it triggers, the full SKILL.md enters context.
skills-lock.json records the source repository and content hash for each installed skill, so you can update them later with the Skills CLI.
Included skills
| Skill | Use it for |
|---|---|
tanstack-start | Server functions, SSR, middleware, deployment |
tanstack-router | File routes, loaders, search params, navigation |
tanstack | Cross-cutting TanStack patterns (Query, Form, etc.) |
kumo-design | Picking and styling Kumo components |
create-auth | Better Auth setup and extending auth flows |
vercel-react-best-practices | React performance patterns |
web-design-guidelines | Accessibility and UI review |
Framework APIs also ship inside installed packages. Before writing TanStack Start or Kumo code, the rules tell the model to read:
| Topic | Read this |
|---|---|
| TanStack Start | node_modules/@tanstack/react-start/skills/react-start/SKILL.md |
| Kumo components | node_modules/@cloudflare/kumo/ai/component-registry.md |
| Kumo setup / theming | node_modules/@cloudflare/kumo/ai/USAGE.md |
| Binding types | worker-configuration.d.ts (generated from wrangler.jsonc) |
Those files match the installed version. Recalled APIs and generic web results often do not.
Skill installation
To add skills, use the Skills CLI:
npx skills add <owner/repo>Browse the catalog at skills.sh. After installing, confirm the skill landed in .agents/skills/ and that skills-lock.json lists it. If you use Claude Code, add a symlink next to the shipped ones:
ln -s ../../.agents/skills/my-custom-skill .claude/skills/my-custom-skillAgents and commands do not need that extra link. .claude/agents and .claude/commands already point at the shared folders.
Creating custom skills
For a workflow that is specific to your product:
Create a directory in .agents/skills/:
mkdir -p .agents/skills/my-custom-skillAdd a SKILL.md file. The description is what triggers the skill, so name the task and the files involved:
---
name: my-custom-skill
description: Handles the notes feature workflow. Use when adding a module under src/modules or when the user asks for a new server function.
---
# My Custom Skill
## Instructions
1. Read `AGENTS.md`, especially Gotchas.
2. Copy the file layout from `src/modules/billing/`.
3. Keep D1 access in `*.server.ts` and UI copy in `messages/en.json` and `messages/es.json`.If you use Claude Code, symlink the directory into .claude/skills/ as shown above. Then ask about the topic in the description and confirm the skill loads.
Subagents
Subagents are specialized assistants that handle one kind of task in their own context window. A long review stays out of the conversation you are using to implement.
Included subagent
Edge Kit ships a read-only code reviewer:
---
name: code-reviewer
description: Reviews code for quality, conventions, and potential issues. Use when reviewing PRs, validating implementations, or checking code before commit.
model: inherit
readonly: true
---
You are a senior code reviewer for TurboStarter Edge...It checks the diff against AGENTS.md and against the configs that enforce the rules (oxlint.config.ts, oxfmt.config.ts, tsconfig.json, wrangler.jsonc). Read-only means it reports issues and does not edit files. The checklist covers:
- TypeScript: no
any, no unsafe casts,interfacefor object shapes, no enums - Imports:
@/only,env.config.tsby relative path, bindings fromcloudflare:workers, Kumo by subpath - Architecture: features in
src/modules/<feature>/, thin routes, D1 and secrets only in*.server.ts - Workers: no Node-only APIs, KV only for short-lived helpers, flags through
src/lib/flags.ts, no extra APM - UI: no literal JSX strings, both message catalogs updated, links from
src/config/paths.ts - Security: Zod on the server,
enforceAuthon protected server functions, no hardcoded secrets
Subagent usage
Invoke one explicitly:
Use the code-reviewer to review the changes in src/modules/billing/Or let the assistant delegate when the task matches the subagent description.
Custom subagents
Add a markdown file under .agents/agents/. Claude picks it up through the existing symlink.
---
name: security-auditor
description: Security specialist. Use when implementing auth, payments, storage keys, or webhooks.
model: inherit
readonly: true
---
You are a security expert auditing TurboStarter Edge.
When invoked:
1. Identify server functions and `src/routes/api/` handlers
2. Confirm protected handlers use `enforceAuth` and check resource ownership
3. Confirm Zod validation runs on the server
4. Confirm secrets stay in `env.config.ts` or Wrangler secrets, never in source
5. Check storage keys for path traversal
Report findings by severity: Critical, High, Medium, Low.Commands
Commands are reusable prompts triggered with a / prefix. They encode a workflow so every feature starts from the same layout.
Included command
/setup-new-feature scaffolds a capability under src/modules/<feature>/, using billing as the reference:
# Setup New Feature
Scaffold a new product capability in TurboStarter Edge following project conventions.
Read `AGENTS.md` first. The `@/*` alias, the i18n import shape, and the no-literal-strings lint rule all bite on the first file you write.The workflow is:
- Put shared infra in
src/lib/and product capabilities insrc/modules/<feature>/. Checksrc/lib/andsrc/modules/common/before adding a helper. - Add Zod schemas, D1 access in
*.server.ts,createServerFnwrappers in*.functions.ts(guarded withenforceAuth), and TanStack Query options in*.queries.ts. - Import Kumo by subpath. Put every user-facing string in
messages/en.jsonandmessages/es.json. - Add a thin file route and a path in
src/config/paths.ts. - If you add a binding, update
wrangler.jsoncand runpnpm cf-typegen. - Finish with
pnpm format:fix && pnpm lint && pnpm test.
The same layout is written up for people in the add a feature recipe.
Command usage
Type / in chat and choose the command:
/setup-new-featureCustom commands
Add a markdown file under .agents/commands/:
# Fix GitHub Issue
Fix a GitHub issue following Edge Kit conventions.
## Steps
1. Use `gh issue view <number>` to get the issue
2. Search `src/modules/` and `src/lib/` for the relevant files
3. Implement the fix using the billing module as the pattern
4. Add a `*.test.ts` or `*.worker.test.ts` next to the change
5. Run `pnpm format:fix && pnpm lint && pnpm test`
6. Commit only when askedModel Context Protocol (MCP)
MCP lets the assistant call external services: issues, databases, designs, and this documentation. That is separate from generating code in the repo.
Common MCP integrations
| Service | Use case |
|---|---|
| GitHub | Create issues, open PRs, read comments |
| Database | Query schemas, inspect data |
| Figma | Import designs for implementation |
| Linear / Jira | Read tickets, update status |
| Browser | Test UI, take screenshots |
For local D1, prefer the Cloudflare local explorer and pnpm db:migrate --local over a Postgres MCP. D1 is SQLite. A Postgres server will not match src/db/.
More servers are listed in the Cursor MCP directory and the MCP server directory.
A typical local server entry looks like this. The filename and the mcpServers key depend on the tool (see the docs server setup below for the exact files Edge Kit expects you to edit):
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${env:GITHUB_TOKEN}"
}
}
}
}Documentation
Edge Kit docs are published with the rest of the TurboStarter docs, in a form assistants can read without copy-paste.
Docs MCP server
A hosted MCP server searches and reads the official docs, including every Edge page:
https://www.turbostarter.dev/mcpYou do not run it locally. Point your client at that URL. It exposes two tools: search_docs (short queries, 2 to 5 words) and read_doc (a docs URL or a .mdx URL).
Create or update .cursor/mcp.json:
{
"mcpServers": {
"turbostarter": {
"url": "https://www.turbostarter.dev/mcp"
}
}
}Enable the server in Cursor settings. After it connects, ask it to search the Edge docs before changing Workers code.
Create or update .mcp.json in the project:
{
"mcpServers": {
"turbostarter": {
"type": "http",
"url": "https://www.turbostarter.dev/mcp"
}
}
}Restart Claude Code and run /mcp to confirm the server is connected.
Create or update .vscode/mcp.json:
{
"servers": {
"turbostarter": {
"type": "http",
"url": "https://www.turbostarter.dev/mcp"
}
}
}Start the server from the MCP controls in VS Code.
Add the server to ~/.codex/config.toml:
[mcp_servers.turbostarter]
type = "http"
url = "https://www.turbostarter.dev/mcp"Restart ChatGPT Codex so it loads the server.
Try a prompt that has to use the docs:
Use the TurboStarter docs MCP server to search for Edge Kit D1 migrations, then read that page and summarize the local vs remote commands.If the client cannot connect, the URL must be exactly https://www.turbostarter.dev/mcp, and the client must support Streamable HTTP. Restart after editing the config, and enable the server in the tool's settings if tools do not appear.
llms.txt
The full documentation index is at /llms.txt, with an Edge Kit section. A single snapshot of every page is at /llms-full.txt. Paste either file into a model with a large enough context window when that model has no MCP client:
Documentation:
{paste documentation here}
---
Based on the above documentation, answer the following:
{your question}Markdown for one page
Each page is available as raw Markdown. Use the Copy Markdown button in the page header, or append .mdx to the URL. This page is /edge/docs/installation/ai-development.mdx.
read_doc accepts that same URL:
{
"url": "/edge/docs/installation/ai-development.mdx"
}Assistant shortcuts
The Open in... control in the page header starts a chat in ChatGPT, Claude, or another assistant with that page attached. Use it when you want one guide in context and you are not inside the repo.
Best practices
These habits matter more on Edge Kit than on a familiar Next.js app, because a wrong default (a barrel import, a Node API, a literal string) fails lint or the Worker bundle.
Development workflow
For anything larger than a one-file change:
- Explore. Have the model read
AGENTS.md,src/modules/billing/, and the files it will touch. - Plan. Ask for a file list: schema,
*.server.ts,*.functions.ts,*.queries.ts, messages, route. - Implement. One step at a time.
- Verify.
pnpm format:fix && pnpm lint && pnpm test.
Small, familiar edits can skip the written plan.
Verification criteria
The model does better when it can check its own work:
Add a createNote server function in src/modules/notes/.
Guard it with enforceAuth. Validate the body with Zod.
Add a worker test that inserts a row and reads it back.
Run pnpm format:fix && pnpm lint && pnpm test when you finish.A passing lint run is not optional here. pnpm lint is the type check.
Prompts
| Strategy | Vague | Specific |
|---|---|---|
| Scope the task | "add tests for billing" | "add a worker test for getBillingSummary in src/modules/billing/, following the existing *.worker.test.ts files, using the D1 binding" |
| Reference patterns | "add a settings form" | "copy the form structure from src/modules/billing/. Import Button from @cloudflare/kumo/components/button. Put new strings in both message catalogs" |
| Describe symptoms | "fix login" | "sign-in returns 500 after session expiry. Start in src/lib/auth/. Write a failing test, then fix it. Do not add a new API route under src/routes/api/" |
Explicit rules
When you extend AGENTS.md, write requirements, not suggestions. "Always call enforceAuth before a D1 write" is followed. "Consider checking auth" is skipped.
## MUST DO
- Verify the session with `enforceAuth` before protected server work
- Run `pnpm format:fix && pnpm lint && pnpm test` before you finish
- Import Kumo by subpath, for example `@cloudflare/kumo/components/button`
- Put user-facing strings in `messages/en.json` and `messages/es.json`
## MUST NOT DO
- Never use `any`. Fix the types.
- Never put binding IDs in `env.config.ts`
- Never import from `@cloudflare/kumo` (the package root)
- Never edit `src/routeTree.gen.ts`, `worker-configuration.d.ts`, or `src/db/schema/auth.ts` by handProject navigation
Point at real paths so the model does not invent a packages/ folder. Edge Kit is one package.
## Where to find things
- Database schema: `src/db/schema/` (`auth.ts` is generated), migrations in `drizzle/`
- Server functions: `src/modules/<feature>/*.functions.ts`
- Shared adapters: `src/lib/`
- Reference feature: `src/modules/billing/`
- UI: Kumo registry in `node_modules/@cloudflare/kumo/ai/component-registry.md`, shared pieces in `src/modules/common/`
- Bindings: `wrangler.jsonc`
- Copy: `messages/en.json`, `messages/es.json`Early corrections
Stop the model when it reaches for Next.js, Prisma, ESLint, or a new top-level src/api/ folder. Most tools interrupt with Esc. After two corrections on the same mistake, start a new conversation and put the constraint in the first message. The failed attempts are still in context otherwise.
Context management
Start a new conversation when you switch features, when the model repeats a mistake, or when a unit of work is done. Continue when you are still iterating on the same module.
Research
Send exploration and review to a subagent so the implementation thread stays small. That includes reading unfamiliar modules, the code-reviewer pass, and a security pass on auth, billing, or storage.
Diff review
Generated code can typecheck and still call a Node API, write a barrel import, or skip messages/es.json. Read the diff. For a new module, run the reviewer subagent in a fresh context after implementation.
Product context
Generic rules produce a generic app. Add the nouns and invariants of your product to AGENTS.md:
## Business domain
This application is a [one-sentence description].
### Entities
- **Account**: the signed-in user from Better Auth
- **Subscription**: Stripe customer, plan id, and status in `src/modules/billing/`
### Rules
- A user can only read rows they own. Check ownership in `*.server.ts`.
- Plan limits are enforced on the server, not only in the UI.Share setups that worked on the Discord. Questions about bindings, D1, and whether a library runs on Workers belong there too.
Troubleshooting
- Confirm
AGENTS.mdis at the repository root - Confirm the file is valid Markdown
- Reopen the project so the tool reloads rules
- Shorten the file if important lines are buried
- Mark critical lines with "MUST" or "IMPORTANT"
The training default is still Next.js. Point at the shipped rules in the prompt: "Read AGENTS.md and follow the Gotchas section. This is TanStack Start on Workers, Kumo by subpath, Oxlint."
If it already edited the wrong files, revert and start a new conversation with that sentence first.
Long sessions push AGENTS.md out of the window, and failed attempts stay in context.
- Start a fresh session for the next feature
- Restate the gotcha when you see drift (
@/only, no JSX literals,pnpm lintfor types) - After two failed corrections, clear context and write a tighter first prompt
- Check that
descriptionnames the task in plain language - Invoke the skill by name
- Confirm
SKILL.mdhas valid YAML frontmatter - For Claude Code, confirm
.claude/skills/<name>symlinks to.agents/skills/<name> - Skills with side effects sometimes need an explicit invocation
- Put the file in
.agents/agents/ - Check the frontmatter for syntax errors
- Confirm
nameanddescriptionare set - Some tools hide subagents until you enable them in settings
Common causes: a Node built-in, a package-root Kumo import, a literal string in JSX, a #/ import, or a binding read from env.config.ts.
- Ask for a check against the Gotchas section before the edit
- Point at
src/modules/billing/instead of describing the API from memory - Run
pnpm format:fix && pnpm lint && pnpm test - Run
pnpm buildif routes or SSR changed - Revert and retry with a narrower prompt if follow-ups keep patching the same mistake
A nested AGENTS.md overrides the root file for the directory it sits in. If they disagree, the model may follow the nearer file.
- Ask which
AGENTS.mdit is using - Keep stack-wide rules in the root file
- Use a nested file only for that folder's domain rules
- Scope the search: "JWT checks in
src/lib/auth/" rather than "find auth" - Use a subagent for exploration
- Name the directory and the suffix (
*.functions.ts,*.server.ts)
- Use
https://www.turbostarter.dev/mcpexactly - Confirm the client supports Streamable HTTP
- Restart the client after changing its MCP config
- Enable the server in the tool's settings if no tools are listed
- Ask explicitly: "Use the TurboStarter docs MCP server to search for …"
- Summarize or compact the session between tasks
- Close the chat when a feature is done
- Keep
node_modules,.output,.wrangler, anddistout of search. They are already in.gitignore
Resources
How is this guide?
Last updated on
Editor setup
Configure your Edge Kit editor with Oxc and Tailwind extensions, apply the repository's formatting settings, and get type-aware feedback while coding.
Conventions
Follow Edge Kit's conventions for module layout, typed imports, server boundaries, localized copy, and the lint checks that enforce them.