|
1 | | -# CLAUDE.md |
| 1 | +# CRITICAL — Read first |
2 | 2 |
|
3 | | -This is a TanStack Start application with React, using Bun as the package |
4 | | -manager. The project is configured for Cloudflare Workers deployment and |
5 | | -includes a comprehensive modern toolchain. |
| 3 | +- Use `bun` for everything: install, scripts, and running tests (`bun test`). |
| 4 | + Reason: the project is bun-native; using npm/pnpm/yarn produces a broken |
| 5 | + lockfile. |
| 6 | +- UI follows the shadcn/ui pattern (components copied into `src/components/ui/`) |
| 7 | + but the primitive layer underneath is `@base-ui/react`, not radix-ui. Reason: |
| 8 | + the project migrated off radix in commit `ca84134`. When adding or updating a |
| 9 | + component, import primitives from `@base-ui/react` — never from `@radix-ui/*`. |
| 10 | +- Never hand-edit generated files: `src/routeTree.gen.ts`, |
| 11 | + `src/db/types.gen.ts`, `worker-configuration.d.ts`. Regenerate with |
| 12 | + `bun run typegen` after schema or route changes. |
6 | 13 |
|
7 | | -**Key Technologies:** |
8 | | - |
9 | | -- TanStack Start (full-stack React framework) |
10 | | -- TanStack Query for data fetching |
11 | | -- Tailwind CSS 4 with shadcn/ui components |
12 | | -- Bun for package management |
13 | | -- TypeScript with strict configuration |
14 | | -- Better-Auth for authentication with GitHub OAuth |
15 | | -- Kysely query builder (via kysely-d1) on Cloudflare D1 SQLite |
16 | | -- Valibot for environment variable validation |
17 | | - |
18 | | -## Common Commands |
19 | | - |
20 | | -**Development:** |
21 | | - |
22 | | -```bash |
23 | | -bun dev # Start development server on port 3000 |
24 | | -bun start # Start production server |
25 | | -``` |
26 | | - |
27 | | -**Code Quality:** |
28 | | - |
29 | | -```bash |
30 | | -bun run check # Run all checks (format, lint, typecheck, tests) |
31 | | -bun run fix # Auto-fix formatting and linting issues |
32 | | -bun run format # Format code with oxfmt |
33 | | -bun run format:check # Check code formatting |
34 | | -bun run lint # Lint code with oxlint |
35 | | -bun run lint:fix # Auto-fix linting issues |
36 | | -bun run typecheck # Run TypeScript type checking |
37 | | -bun test # Run the test suite |
38 | | -``` |
39 | | - |
40 | | -**Database:** |
41 | | - |
42 | | -```bash |
43 | | -bun run db:migrate # Apply database migrations (local) |
44 | | -bun run db:migrate:prod # Apply database migrations (production) |
45 | | -bun run db:reset # Reset database (clean + migrate) |
46 | | -``` |
47 | | - |
48 | | -**Build & Deployment:** |
| 14 | +## Commands |
49 | 15 |
|
50 | 16 | ```bash |
51 | | -bun run build # Build for production |
52 | | -bun run clean # Clean cache directories |
53 | | -bun run nuke # Clean everything including node_modules |
| 17 | +bun dev # dev server on :3000 |
| 18 | +bun run check # format:check + lint + test (lint includes typecheck) |
| 19 | +bun run fix # auto-fix format + lint |
| 20 | +bun test # bun's built-in test runner |
| 21 | +bun run db:migrate # apply D1 migrations (local) |
| 22 | +bun run db:migrate:prod # apply D1 migrations (production) |
| 23 | +bun run typegen # regenerate worker + Kysely types |
54 | 24 | ``` |
55 | 25 |
|
56 | | -**Setup & Utilities:** |
57 | | - |
58 | | -```bash |
59 | | -bun run setup # Initial project setup (install, env, migrate) |
60 | | -bun run outdated # Check for package updates interactively |
61 | | -bun run typegen # Generate Cloudflare Worker types |
62 | | -``` |
63 | | - |
64 | | -## Architecture |
65 | | - |
66 | | -**Router Configuration:** |
67 | | - |
68 | | -- File-based routing with `src/routes/` directory |
69 | | -- Route tree auto-generated in `src/routeTree.gen.ts` |
70 | | -- Root route in `src/routes/__root.tsx` includes global providers and error |
71 | | - boundaries |
72 | | -- Router configured with TanStack Query integration in `src/router.tsx` |
73 | | - |
74 | | -**Component Organization:** |
75 | | - |
76 | | -- `src/components/ui/` - shadcn/ui components |
77 | | -- `src/components/layout/` - Layout components (header, footer) |
78 | | -- `src/components/themes/` - Theme provider and picker |
79 | | -- `src/components/errors/` - Error boundaries and not found pages |
80 | | -- `src/components/dev/` - Development-only components (devtools, indicators) |
81 | | - |
82 | | -**Database & Authentication:** |
83 | | - |
84 | | -- `src/db/` - Database client and type definitions |
85 | | - - `src/db/client.ts` - Kysely database client for Cloudflare D1 |
86 | | - - `src/db/types.ts` - Kysely `Database` interface describing the schema |
87 | | -- `src/lib/auth.ts` - Better-Auth server configuration |
88 | | -- `src/lib/auth-client.ts` - Better-Auth client utilities |
89 | | -- `src/env.ts` - Environment variable validation with Valibot |
90 | | -- `migrations/` - Hand-written D1 SQL migrations |
91 | | -- `wrangler.jsonc` - Cloudflare Workers configuration with D1 binding |
92 | | - |
93 | | -**Configuration:** |
94 | | - |
95 | | -- `src/config/site-config.ts` - Site-wide configuration |
96 | | -- `src/lib/` - Utility functions, API functions, and shared logic |
97 | | -- `src/styles/` - Global CSS including Tailwind base styles |
98 | | - |
99 | | -**Key Patterns:** |
100 | | - |
101 | | -- Uses `@/` path alias for src directory |
102 | | -- TanStack Query client integrated into router context |
103 | | -- Theme system with system/light/dark mode support |
104 | | -- Font preloading with Geist variable fonts |
105 | | -- API routes in `src/routes/api/` directory |
106 | | -- Better-Auth integration with GitHub OAuth provider |
107 | | -- Kysely query builder on Cloudflare D1 SQLite (via kysely-d1) |
108 | | -- Cloudflare Workers deployment target with D1 binding |
109 | | -- Valibot schema validation for type-safe environment variables |
110 | | -- Layout routes (`_main.tsx`, `_auth.tsx`) for route grouping |
111 | | - |
112 | | -## Development Notes |
113 | | - |
114 | | -**Vite Configuration:** |
115 | | - |
116 | | -- Target: Cloudflare Module Workers |
117 | | -- Default port: 3000 |
118 | | -- Uses Rolldown-powered Vite with React OXC plugin for faster compilation |
119 | | -- Includes TypeScript path mapping support |
120 | | -- Tailwind CSS 4 integration via `@tailwindcss/vite` |
121 | | -- Cloudflare plugin for SSR environment |
122 | | - |
123 | | -**Database Configuration:** |
124 | | - |
125 | | -- Kysely query builder via `kysely-d1`'s `D1Dialect` |
126 | | -- Hand-written SQL migrations in `migrations/`, applied via |
127 | | - `wrangler d1 migrations apply` |
128 | | -- Better-Auth uses its built-in Kysely D1 adapter (pass `env.DB` directly) |
129 | | -- Local development uses Wrangler's local D1 database |
130 | | -- Database binding configured as `DB` in `wrangler.jsonc` |
131 | | - |
132 | | -**Authentication Setup:** |
133 | | - |
134 | | -- Better-Auth with GitHub OAuth provider |
135 | | -- Environment variables: `BETTER_AUTH_SECRET`, `BETTER_AUTH_URL`, |
136 | | - `OAUTH_GITHUB_CLIENT_ID`, `OAUTH_GITHUB_CLIENT_SECRET` |
137 | | -- Auto-generated secret via `dotkit` during setup |
138 | | -- API routes handle auth at `src/routes/api/auth/$.ts` |
139 | | - |
140 | | -**Linting & Formatting:** |
141 | | - |
142 | | -- OxLint for fast linting (configured in `.oxlintrc.json`) |
143 | | -- OxFmt for code formatting (configured in `.oxfmtrc.jsonc`) |
144 | | -- Both powered by the OXC toolchain for speed |
145 | | - |
146 | | -**Package Manager:** |
147 | | - |
148 | | -- Uses Bun for all operations |
149 | | -- Lock file: `bun.lock` |
150 | | -- TypeScript and React 19 compatible |
151 | | -- Setup script at `bin/setup` handles initial configuration |
| 26 | +## Stack conventions |
| 27 | + |
| 28 | +- **Framework.** TanStack Start (Router + Query + Vite) deployed to Cloudflare |
| 29 | + Workers. Not Next.js — do not reach for Next.js APIs (`next/*`, App Router |
| 30 | + primitives, etc.). |
| 31 | +- **Routing.** File-based under `src/routes/`. Layout routes use `_main.tsx` / |
| 32 | + `_auth.tsx` prefixes. API routes live under `src/routes/api/`. The route tree |
| 33 | + is generated into `src/routeTree.gen.ts` at dev/build. |
| 34 | +- **Database.** Kysely on Cloudflare D1 via `kysely-d1`'s `D1Dialect` with |
| 35 | + `CamelCasePlugin` registered. Write TypeScript in camelCase; SQL columns stay |
| 36 | + snake_case — the plugin maps between them. Get a client from `getDb()` in |
| 37 | + `src/db/client.ts`, which reads `env.DB` from `cloudflare:workers`. |
| 38 | +- **Migrations.** Hand-written SQL in `migrations/`. After adding or editing a |
| 39 | + migration, run `bun run db:types` (or `bun run typegen`) to refresh |
| 40 | + `src/db/types.gen.ts`. Types are derived by replaying migrations into a |
| 41 | + scratch Bun SQLite DB via `kysely-codegen` — there is no live-DB introspection |
| 42 | + step. |
| 43 | +- **Auth.** Better-Auth with GitHub OAuth, using its built-in Kysely D1 adapter |
| 44 | + (pass `env.DB` directly). Server config in `src/lib/auth.ts`, client in |
| 45 | + `src/lib/auth-client.ts`, routes mounted at `src/routes/api/auth/$.ts`. |
| 46 | +- **Env vars.** Validated in `src/env.ts` with Valibot. Add new variables to |
| 47 | + that schema — do not read `process.env` directly elsewhere in the app. |
| 48 | +- **Styling.** Tailwind CSS 4 via `@tailwindcss/vite`. Global styles in |
| 49 | + `src/styles/`. |
| 50 | +- **Imports.** Use the `@/` alias for `src/`; avoid relative paths across module |
| 51 | + boundaries. |
| 52 | +- **Lint / format.** `oxlint` and `oxfmt` (OXC toolchain). `oxlint` runs |
| 53 | + typechecking via `oxlint-tsgolint`, so there is no separate `tsc` step — don't |
| 54 | + add a `typecheck` script or reach for `tsc --noEmit`. Do not introduce ESLint |
| 55 | + or Prettier. |
| 56 | + |
| 57 | +# CRITICAL — Read last |
| 58 | + |
| 59 | +- Use `bun`, not `npm`/`pnpm`/`yarn`. `bun test` is the test runner — there is |
| 60 | + no vitest or jest. |
| 61 | +- UI uses the shadcn/ui pattern with `@base-ui/react` primitives — never import |
| 62 | + from `@radix-ui/*`. |
| 63 | +- Never edit generated files (`routeTree.gen.ts`, `db/types.gen.ts`, |
| 64 | + `worker-configuration.d.ts`) — regenerate with `bun run typegen`. |
0 commit comments