|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Repository Overview |
| 6 | + |
| 7 | +TanStack AI is a type-safe, provider-agnostic AI SDK for building AI-powered applications. The repository is a **pnpm monorepo** managed with **Nx** that includes TypeScript, PHP, and Python packages, plus multiple framework examples. |
| 8 | + |
| 9 | +## Package Manager & Tooling |
| 10 | + |
| 11 | +- **Package Manager **: [email protected] (required) |
| 12 | +- **Build System**: Nx for task orchestration and caching |
| 13 | +- **TypeScript**: 5.9.3 |
| 14 | +- **Testing**: Vitest for unit tests |
| 15 | +- **Linting**: ESLint with custom TanStack config |
| 16 | +- **Formatting**: Prettier |
| 17 | + |
| 18 | +## Common Commands |
| 19 | + |
| 20 | +### Testing |
| 21 | + |
| 22 | +```bash |
| 23 | +# Run all tests (full CI suite) |
| 24 | +pnpm test |
| 25 | + |
| 26 | +# Run tests for affected packages only (for PRs) |
| 27 | +pnpm test:pr |
| 28 | + |
| 29 | +# Run specific test suites |
| 30 | +pnpm test:lib # Run unit tests for affected packages |
| 31 | +pnpm test:lib:dev # Watch mode for unit tests |
| 32 | +pnpm test:eslint # Lint affected packages |
| 33 | +pnpm test:types # Type check affected packages |
| 34 | +pnpm test:build # Verify build artifacts with publint |
| 35 | +pnpm test:coverage # Generate coverage reports |
| 36 | +pnpm test:knip # Check for unused dependencies |
| 37 | +pnpm test:sherif # Check pnpm workspace consistency |
| 38 | +pnpm test:docs # Verify documentation links |
| 39 | +``` |
| 40 | + |
| 41 | +### Testing Individual Packages |
| 42 | + |
| 43 | +```bash |
| 44 | +# Navigate to package directory and run tests |
| 45 | +cd packages/typescript/ai |
| 46 | +pnpm test:lib # Run tests for this package |
| 47 | +pnpm test:lib:dev # Watch mode |
| 48 | +pnpm test:types # Type check |
| 49 | +pnpm test:eslint # Lint |
| 50 | +``` |
| 51 | + |
| 52 | +### Building |
| 53 | + |
| 54 | +```bash |
| 55 | +# Build affected packages |
| 56 | +pnpm build |
| 57 | + |
| 58 | +# Build all packages |
| 59 | +pnpm build:all |
| 60 | + |
| 61 | +# Watch mode (build + watch for changes) |
| 62 | +pnpm watch |
| 63 | +pnpm dev # alias for watch |
| 64 | +``` |
| 65 | + |
| 66 | +### Code Quality |
| 67 | + |
| 68 | +```bash |
| 69 | +pnpm format # Format all files with Prettier |
| 70 | +``` |
| 71 | + |
| 72 | +### Changesets (Release Management) |
| 73 | + |
| 74 | +```bash |
| 75 | +pnpm changeset # Create a new changeset |
| 76 | +pnpm changeset:version # Bump versions based on changesets |
| 77 | +pnpm changeset:publish # Publish to npm |
| 78 | +``` |
| 79 | + |
| 80 | +## Architecture |
| 81 | + |
| 82 | +### Monorepo Structure |
| 83 | + |
| 84 | +``` |
| 85 | +packages/ |
| 86 | +├── typescript/ # TypeScript packages (main implementation) |
| 87 | +│ ├── ai/ # Core AI library (@tanstack/ai) |
| 88 | +│ ├── ai-client/ # Framework-agnostic chat client |
| 89 | +│ ├── ai-react/ # React hooks (useChat) |
| 90 | +│ ├── ai-solid/ # Solid hooks |
| 91 | +│ ├── ai-svelte/ # Svelte integration |
| 92 | +│ ├── ai-vue/ # Vue integration |
| 93 | +│ ├── ai-openai/ # OpenAI adapter |
| 94 | +│ ├── ai-anthropic/ # Anthropic/Claude adapter |
| 95 | +│ ├── ai-gemini/ # Google Gemini adapter |
| 96 | +│ ├── ai-ollama/ # Ollama adapter |
| 97 | +│ ├── ai-devtools/ # DevTools integration |
| 98 | +│ ├── react-ai-devtools/ # React DevTools component |
| 99 | +│ └── solid-ai-devtools/ # Solid DevTools component |
| 100 | +├── php/ # PHP packages (future) |
| 101 | +└── python/ # Python packages (future) |
| 102 | +
|
| 103 | +examples/ # Example applications |
| 104 | +├── ts-react-chat/ # React chat example |
| 105 | +├── ts-solid-chat/ # Solid chat example |
| 106 | +├── ts-vue-chat/ # Vue chat example |
| 107 | +├── ts-svelte-chat/ # Svelte chat example |
| 108 | +├── ts-group-chat/ # Multi-user group chat |
| 109 | +├── vanilla-chat/ # Vanilla JS example |
| 110 | +├── php-slim/ # PHP Slim framework example |
| 111 | +└── python-fastapi/ # Python FastAPI example |
| 112 | +``` |
| 113 | + |
| 114 | +### Core Architecture Concepts |
| 115 | + |
| 116 | +#### 1. Adapter System (Tree-Shakeable) |
| 117 | + |
| 118 | +The library uses a **tree-shakeable adapter architecture** where each provider (OpenAI, Anthropic, Gemini, Ollama) exports multiple specialized adapters: |
| 119 | + |
| 120 | +- **Text adapters** (`openaiText`, `anthropicText`) - Chat/completion |
| 121 | +- **Embedding adapters** (`openaiEmbed`) - Text embeddings |
| 122 | +- **Summarize adapters** (`openaiSummarize`) - Summarization |
| 123 | +- **Image adapters** (`openaiImage`) - Image generation |
| 124 | + |
| 125 | +Each adapter is a separate import to minimize bundle size: |
| 126 | + |
| 127 | +```typescript |
| 128 | +import { openaiText } from '@tanstack/ai-openai/adapters' |
| 129 | +import { ai } from '@tanstack/ai' |
| 130 | + |
| 131 | +const textAdapter = openaiText() |
| 132 | +const result = ai({ adapter: textAdapter, model: 'gpt-4o', messages: [...] }) |
| 133 | +``` |
| 134 | + |
| 135 | +#### 2. Core Functions |
| 136 | + |
| 137 | +The `@tanstack/ai` package provides core functions: |
| 138 | + |
| 139 | +- **`ai()`** / **`generate()`** - Unified generation function for any adapter type |
| 140 | +- **`chat()`** - Chat completion with streaming, tools, and agent loops |
| 141 | +- **`embedding()`** - Generate embeddings |
| 142 | +- **`summarize()`** - Summarize text |
| 143 | +- Legacy adapters (monolithic, deprecated) use `openai()`, `anthropic()`, etc. |
| 144 | + |
| 145 | +#### 3. Isomorphic Tool System |
| 146 | + |
| 147 | +Tools are defined once with `toolDefinition()` and can have `.server()` or `.client()` implementations: |
| 148 | + |
| 149 | +```typescript |
| 150 | +const tool = toolDefinition({ |
| 151 | + name: 'getTodos', |
| 152 | + inputSchema: z.object({ userId: z.string() }), |
| 153 | + outputSchema: z.array(z.object({ id: z.string(), title: z.string() })), |
| 154 | +}) |
| 155 | + |
| 156 | +// Server implementation (runs on server) |
| 157 | +const serverTool = tool.server(async ({ userId }) => db.todos.find({ userId })) |
| 158 | + |
| 159 | +// Client implementation (runs in browser) |
| 160 | +const clientTool = tool.client(async ({ userId }) => |
| 161 | + fetch(`/api/todos/${userId}`), |
| 162 | +) |
| 163 | +``` |
| 164 | + |
| 165 | +#### 4. Framework Integrations |
| 166 | + |
| 167 | +- **`@tanstack/ai-client`** - Headless chat state management with connection adapters (SSE, HTTP stream, custom) |
| 168 | +- **`@tanstack/ai-react`** - `useChat` hook for React |
| 169 | +- **`@tanstack/ai-solid`** - `useChat` hook for Solid |
| 170 | +- **`@tanstack/ai-vue`** - Vue integration |
| 171 | +- **`@tanstack/ai-svelte`** - Svelte integration |
| 172 | + |
| 173 | +Each framework integration uses the headless `ai-client` under the hood. |
| 174 | + |
| 175 | +#### 5. Type Safety Features |
| 176 | + |
| 177 | +- **Per-model type safety** - Provider options are typed based on selected model |
| 178 | +- **Multimodal content** - Type-safe image, audio, video, document support based on model capabilities |
| 179 | +- **Zod schema inference** - Tools use Zod for runtime validation and type inference |
| 180 | +- **`InferChatMessages`** - Type inference for message types based on tools and configuration |
| 181 | + |
| 182 | +### Key Files & Directories |
| 183 | + |
| 184 | +#### Core Package (`packages/typescript/ai/src/`) |
| 185 | + |
| 186 | +- **`index.ts`** - Main exports (chat, embedding, summarize, toolDefinition, etc.) |
| 187 | +- **`types.ts`** - Core type definitions (ModelMessage, ContentPart, StreamChunk, etc.) |
| 188 | +- **`core/`** - Core functions (chat.ts, generate.ts, embedding.ts, summarize.ts) |
| 189 | +- **`adapters/`** - Base adapter classes and interfaces |
| 190 | +- **`tools/`** - Tool definition system and Zod converter |
| 191 | +- **`stream/`** - Stream processing (StreamProcessor, chunking strategies, partial JSON parsing) |
| 192 | +- **`utilities/`** - Helpers (message converters, agent loop strategies, SSE utilities) |
| 193 | + |
| 194 | +#### Provider Adapters (e.g., `packages/typescript/ai-openai/src/`) |
| 195 | + |
| 196 | +- **`index.ts`** - Exports tree-shakeable adapters (openaiText, openaiEmbed, etc.) |
| 197 | +- **`adapters/`** - Individual adapter implementations (text.ts, embed.ts, summarize.ts, image.ts) |
| 198 | +- **`model-meta.ts`** - Model metadata for type safety (provider options per model) |
| 199 | +- **`openai-adapter.ts`** - Legacy monolithic adapter (deprecated) |
| 200 | + |
| 201 | +## Development Workflow |
| 202 | + |
| 203 | +### Adding a New Feature |
| 204 | + |
| 205 | +1. Create a changeset: `pnpm changeset` |
| 206 | +2. Make changes in the appropriate package(s) |
| 207 | +3. Run tests: `pnpm test:lib` (or package-specific tests) |
| 208 | +4. Run type checks: `pnpm test:types` |
| 209 | +5. Run linter: `pnpm test:eslint` |
| 210 | +6. Format code: `pnpm format` |
| 211 | +7. Verify build: `pnpm test:build` or `pnpm build` |
| 212 | + |
| 213 | +### Working with Examples |
| 214 | + |
| 215 | +Examples are not built by Nx. To run an example: |
| 216 | + |
| 217 | +```bash |
| 218 | +cd examples/ts-react-chat |
| 219 | +pnpm install # if needed |
| 220 | +pnpm dev # start dev server |
| 221 | +``` |
| 222 | + |
| 223 | +### Nx Workspace |
| 224 | + |
| 225 | +- Uses Nx affected commands to only test/build changed packages |
| 226 | +- Nx caching speeds up builds and tests |
| 227 | +- `nx.json` configures Nx behavior |
| 228 | +- Use `nx run-many` to run commands across multiple packages |
| 229 | + |
| 230 | +## Important Conventions |
| 231 | + |
| 232 | +### Workspace Dependencies |
| 233 | + |
| 234 | +- Use `workspace:*` protocol for internal package dependencies in `package.json` |
| 235 | +- Example: `"@tanstack/ai": "workspace:*"` |
| 236 | + |
| 237 | +### Tree-Shakeable Exports |
| 238 | + |
| 239 | +When adding new functionality to provider adapters, create separate adapters rather than adding to monolithic ones. Export from `/adapters` subpath. |
| 240 | + |
| 241 | +### Exports Field |
| 242 | + |
| 243 | +Each package uses `exports` field in package.json for subpath exports (e.g., `@tanstack/ai/adapters`, `@tanstack/ai/event-client`) |
| 244 | + |
| 245 | +### Testing Strategy |
| 246 | + |
| 247 | +- Unit tests in `*.test.ts` files alongside source |
| 248 | +- Uses Vitest with happy-dom for DOM testing |
| 249 | +- Test coverage via `pnpm test:coverage` |
| 250 | + |
| 251 | +### Documentation |
| 252 | + |
| 253 | +- Docs are in `docs/` directory (Markdown) |
| 254 | +- Auto-generated docs via `pnpm generate-docs` (TypeDoc) |
| 255 | +- Link verification via `pnpm test:docs` |
| 256 | + |
| 257 | +## Key Dependencies |
| 258 | + |
| 259 | +### Core Runtime Dependencies |
| 260 | + |
| 261 | +- `zod` - Schema validation (peer dependency) |
| 262 | +- `@alcyone-labs/zod-to-json-schema` - Convert Zod schemas to JSON Schema for LLM tools |
| 263 | +- `partial-json` - Parse incomplete JSON from streaming responses |
| 264 | + |
| 265 | +### Provider SDKs (in adapter packages) |
| 266 | + |
| 267 | +- `openai` - OpenAI SDK |
| 268 | +- `@anthropic-ai/sdk` - Anthropic SDK |
| 269 | +- `@google/generative-ai` - Gemini SDK |
| 270 | +- `ollama` - Ollama SDK |
| 271 | + |
| 272 | +### DevTools |
| 273 | + |
| 274 | +- `@tanstack/devtools-event-client` - TanStack DevTools integration |
0 commit comments