CLAUDE.md
CLAUDE.mdCLAUDE.mdroot
Quality
97/100
Scores the file, not the repository.Length
1,119 words
29 headings · 4 code blocksRepository
1.4k
— · pushed 4 days agoLast changed
3 days ago
First indexed 3 days ago.1# CLAUDE.md23This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.45## Project Overview67This is the Next.js frontend for egghead.io, an online learning platform. It requires the `egghead-rails` backend to be running for full functionality.89## Essential Commands1011```bash12# Install dependencies (MUST use pnpm)13pnpm install1415# Development16pnpm dev # Start Next.js dev server on port 300017pnpm dev:concurrent # Run dev server + Inngest dev server1819# Testing20pnpm test # Run tests in watch mode21pnpm test:ci # Run tests once (for CI)2223# Code Quality24pnpm lint # Run ESLint with auto-fix25pnpm format # Run Prettier on all files26pnpm build # Production build (also runs type checking)2728# Sanity CMS29pnpm sanity # Start Sanity Studio30```3132## Architecture Overview3334### Tech Stack3536- **Framework**: Next.js 14.2.4 with React 18.3.137- **Language**: TypeScript with strict mode38- **Styling**: Tailwind CSS + CSS Modules39- **State Management**: XState (state machines), React hooks, tRPC (server state)40- **Database**: Postgres41- **CMS**: Sanity42- **Video**: Mux43- **Payments**: Stripe44- **Authentication**: Custom auth via app.egghead.io45- **Search**: Typesense4647### Directory Structure4849```50src/51├── app/ # Next.js 13+ app directory (new routing)52├── pages/ # Legacy pages directory (being migrated)53├── components/ # React components (feature-based organization)54├── lib/ # Core utilities and API clients55├── server/ # tRPC routers and server-side logic56├── hooks/ # Custom React hooks57├── inngest/ # Event-driven background jobs58├── machines/ # XState state machines59└── utils/ # Pure utility functions60```6162### Key Patterns63641. **Component Organization**: Feature-based folders (e.g., `components/posts/`, `components/workshop/claude-code/`)652. **Path Aliases**: Use `@/` for imports from `src/` directory663. **Data Fetching**: Use tRPC for type-safe API calls674. **Styling**: Prefer Tailwind utilities, use CSS modules for complex styles685. **State Machines**: Use XState for complex UI states696. **Testing**: Co-locate tests in `__tests__` folders or `*.test.ts` files707. **Code Organization**: Follow separation of concerns - extract schemas, database logic, and UI components into separate modules7172### Preferred Code Organization Structure7374When working with large files or creating new features, follow this separation of concerns pattern:7576#### 1. Schemas and Types (`src/schemas/`)7778- Extract all Zod schemas and TypeScript types into dedicated schema files79- Example: `src/schemas/post.ts` for post-related types80- Export both schemas and inferred types: `export type Post = z.infer<typeof PostSchema>`8182#### 2. Database Operations (`src/lib/[feature]/` or `src/lib/[feature]-query.ts`)8384- Extract database queries and data fetching logic85- Use `'use server'` directive for server-side operations86- Create utility functions for common operations87- Structure:88```89 src/lib/posts/90 ├── get-post.ts # Main data fetching91 ├── get-tags.ts # Related data fetching92 ├── get-course.ts # Associated data93 └── utils.ts # Utility functions94 src/lib/posts-query.ts # Main export file95```9697#### 3. UI Components (`src/components/[feature]/`)9899- Extract reusable UI components into feature folders100- Keep components focused on single responsibilities101- Include prop interfaces and proper TypeScript types102- Structure:103```104 src/components/posts/105 ├── post-player.tsx # Main interactive components106 ├── instructor-profile.tsx # Data display components107 ├── tag-list.tsx # List components108 ├── powered-by-mux.tsx # Utility components109 └── icons/110 └── github-icon.tsx # Icon components111```112113#### 4. Main Page/Route Files114115- Keep page files focused on orchestration and layout116- Import from extracted modules rather than inline definitions117- Target: Reduce page files to ~200-300 lines maximum118- Handle only: data fetching orchestration, layout, and SEO119120**When to apply this structure:**121122- Files exceeding 500+ lines123- Multiple responsibilities in a single file (data fetching + UI + types)124- Difficulty finding specific functionality125- Need to reuse components elsewhere126- Components that could benefit from isolated testing127128**Benefits of this approach:**129130- **Maintainability**: Each piece has a single responsibility131- **Testability**: Components and functions can be tested in isolation132- **Reusability**: Components can be used elsewhere in the app133- **Performance**: Better code splitting and bundle optimization134- **Developer Experience**: Easier to find and modify specific functionality135136**Real-world example:** The `src/pages/[post].tsx` was refactored from 967 lines to 262 lines following this pattern.137138## Development Setup1391401. Ensure Node.js 18.17.1 is installed (check `.nvmrc`)1412. Install dependencies: `pnpm install`1423. Pull environment variables: `vercel env pull .env.local`1434. Start the Rails backend: `cd ../egghead-rails && foreman start`1445. Configure Stripe webhooks if working with payments1456. Start development: `pnpm dev`146147## Testing Approach148149- Jest with React Testing Library150- Tests live alongside source files151- Run single test: `pnpm test -- path/to/test`152- Mock external dependencies (Stripe, Mux, etc.)153- Use XState testing utilities for state machines154155## Pre-commit Checks156157Husky automatically runs:1581591. Prettier formatting on all files1602. ESLint with auto-fix on TypeScript files161162## Common Tasks163164### Adding a New Page165166- Use app directory: `src/app/your-page/page.tsx`167- Follow existing patterns for data fetching and layouts168169### Creating Components170171- Check existing components first for patterns (see `src/components/posts/` for reference)172- Use TypeScript interfaces for props173- Follow accessibility best practices174- Extract components into feature-based folders (e.g., `src/components/[feature]/`)175- Keep components focused on single responsibilities176- For large page files, extract UI components following the preferred code organization structure177178### Working with tRPC179180- Routers in `src/server/routers/`181- Use `trpc.useQuery()` for data fetching182- Type safety is automatic183184### Sanity CMS185186- Studio runs at `/studio`187- Schema files in `studio/schemas/`188- Use GROQ queries for data fetching189190## Important Notes191192- Always use `pnpm` (not npm or yarn)193- The project uses both app/ and pages/ directories (migration in progress)194- Environment variables come from Vercel195- Backend must be running for most features196- Check `src/lib/` for existing utilities before creating new ones197198## Working with Course Builder Database199200The project integrates with a separate Course Builder database for new course content. Key patterns:201202### Database Connection203204- Uses `mysql2/promise` with connection pooling205- Connection string from `COURSE_BUILDER_DATABASE_URL` env var206- Always use the existing `getConnectionPool()` function in `src/lib/get-course-builder-metadata.ts`207208### Important Patterns2092101. **Server-Side Only**: MySQL connections must run server-side only211212 - Create wrapper functions that check `typeof window === 'undefined'`213 - Use dynamic imports inside the wrapper: `await import('./get-course-builder-metadata')`214 - Never import mysql2 directly in files that could be bundled for client215 - See `load-course-builder-metadata-wrapper.ts` for the pattern2162172. **Query Patterns**:218219 - Content is stored in `egghead_ContentResource` table220 - Use flexible slug matching: `id = ? OR JSON_UNQUOTE(JSON_EXTRACT(fields, '$.slug')) = ?`221 - Fields are JSON, parse with: `typeof row.fields === 'string' ? JSON.parse(row.fields) : row.fields`2222233. **Content Types**:224225 - Posts with `type = 'post'` and `fields.postType = 'course'` are courses226 - Video resources have `type = 'videoResource'`227 - Relationships via `egghead_ContentResourceResource` join table2282294. **Error Handling**:230 - Always release connections in finally block: `conn.release()`231 - Return `null` for missing data, not errors232 - Log helpful debug messages for troubleshooting233
Also in skillrecordings/egghead-next
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| skillrecordings/egghead-next.cursor/rules/_global.mdc · 1.4k | Cursor rules | teststyletypesgit+1 | 89/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/benchmarks-create.mdc · 1.4k | Cursor rules | no sections | 38/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/cli-github-search.mdc · 1.4k | Cursor rules | no sections | 51/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/cli-pack.mdc · 1.4k | Cursor rules | arch | 52/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/cli-worktree.mdc · 1.4k | Cursor rules | setupgit | 56/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/cli-wrangler.mdc · 1.4k | Cursor rules | styledatabase | 52/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/docs-diagram.mdc · 1.4k | Cursor rules | styledo-not | 65/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/docs-openapi-spec.mdc · 1.4k | Cursor rules | archapi | 58/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/docs-prd.mdc · 1.4k | Cursor rules | archagent-behaviourdocs | 58/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/docs-structure.mdc · 1.4k | Cursor rules | archdocs | 49/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/docs-sync.mdc · 1.4k | Cursor rules | docs | 45/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/docs-tech-stack.mdc · 1.4k | Cursor rules | testlint-formatarchagent-behaviour+1 | 58/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/gh-docs-sync.mdc · 1.4k | Cursor rules | docs | 53/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/gh-task-plan.mdc · 1.4k | Cursor rules | teststylearchtypes+2 | 96/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/logging-session.mdc · 1.4k | Cursor rules | lint-formatstylearchgit | 62/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/pnpm-fixes.mdc · 1.4k | Cursor rules | setupbuildstyledependencies | 68/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-todos-next.mdc · 1.4k | Cursor rules | docs | 45/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-update-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 96/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-update-user-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 96/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/prompt-improve.mdc · 1.4k | Cursor rules | style | 38/100 | 3 days ago |
Diff against .cursor/rules/_global.mdc Diff against .cursor/rules/benchmarks-create.mdc Diff against .cursor/rules/cli-github-search.mdc Diff against .cursor/rules/cli-pack.mdc Diff against .cursor/rules/cli-worktree.mdc Diff against .cursor/rules/cli-wrangler.mdc Diff against .cursor/rules/docs-diagram.mdc Diff against .cursor/rules/docs-openapi-spec.mdc Diff against .cursor/rules/docs-prd.mdc Diff against .cursor/rules/docs-structure.mdc Diff against .cursor/rules/docs-sync.mdc Diff against .cursor/rules/docs-tech-stack.mdc Diff against .cursor/rules/gh-docs-sync.mdc Diff against .cursor/rules/gh-task-plan.mdc Diff against .cursor/rules/logging-session.mdc Diff against .cursor/rules/pnpm-fixes.mdc Diff against .cursor/rules/project-todos-next.mdc Diff against .cursor/rules/project-update-rules.mdc Diff against .cursor/rules/project-update-user-rules.mdc Diff against .cursor/rules/prompt-improve.mdc
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| filamentphp/filamentCLAUDE.md · 32k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 950 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 3 days ago | |
| microsoft/playwrightCLAUDE.md · 94k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| dotCMS/coreCLAUDE.md · 950 | CLAUDE.md | setupbuildteststyle+7 | 99/100 | 3 days ago | |
| lollipopkit/flutter_server_boxCLAUDE.md · 8.3k | CLAUDE.md | buildteststylearch+2 | 98/100 | 3 days ago |
