|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +Bulletproof React is a scalable React application architecture that provides opinionated guidelines and best practices for building production-ready React applications. The project includes three different implementations: |
| 6 | + |
| 7 | +- **React Vite**: Modern Vite-based React application |
| 8 | +- **Next.js App Router**: Next.js 13+ with App Router |
| 9 | +- **Next.js Pages**: Traditional Next.js with Pages Router |
| 10 | + |
| 11 | +### Application Domain |
| 12 | +The demo application is a team collaboration platform where users can: |
| 13 | +- Create and join teams |
| 14 | +- Start discussions within teams |
| 15 | +- Comment on discussions |
| 16 | +- Manage user roles (ADMIN/USER permissions) |
| 17 | + |
| 18 | +**Live Demo**: [https://bulletproof-react-app.netlify.app](https://bulletproof-react-app.netlify.app) |
| 19 | + |
| 20 | +## Setup Commands |
| 21 | + |
| 22 | +```bash |
| 23 | +# Navigate to desired app |
| 24 | +cd apps/react-vite # or apps/nextjs-app or apps/nextjs-pages |
| 25 | + |
| 26 | +# Install dependencies |
| 27 | +yarn install |
| 28 | + |
| 29 | +# Start development server |
| 30 | +yarn dev |
| 31 | + |
| 32 | +# Run tests |
| 33 | +yarn test |
| 34 | + |
| 35 | +# Run e2e tests |
| 36 | +yarn test:e2e |
| 37 | + |
| 38 | +# Lint code |
| 39 | +yarn lint |
| 40 | + |
| 41 | +# Build for production |
| 42 | +yarn build |
| 43 | +``` |
| 44 | + |
| 45 | +## Project Structure |
| 46 | + |
| 47 | +The codebase follows a feature-based architecture organized as follows: |
| 48 | + |
| 49 | +``` |
| 50 | +src/ |
| 51 | +├── app/ # Application layer (routes, providers, router) |
| 52 | +├── components/ # Shared UI components |
| 53 | +├── config/ # Global configurations and env variables |
| 54 | +├── features/ # Feature-based modules (auth, discussions, comments, etc.) |
| 55 | +├── hooks/ # Shared React hooks |
| 56 | +├── lib/ # Preconfigured libraries (react-query, auth, etc.) |
| 57 | +├── testing/ # Test utilities and mocks |
| 58 | +├── types/ # Shared TypeScript types |
| 59 | +└── utils/ # Shared utility functions |
| 60 | +``` |
| 61 | + |
| 62 | +### Feature Structure |
| 63 | +Each feature should be self-contained: |
| 64 | + |
| 65 | +``` |
| 66 | +src/features/awesome-feature/ |
| 67 | +├── api/ # API calls and hooks for this feature |
| 68 | +├── components/ # Feature-specific components |
| 69 | +├── hooks/ # Feature-specific hooks |
| 70 | +├── stores/ # Feature-specific state |
| 71 | +├── types/ # Feature-specific types |
| 72 | +└── utils/ # Feature-specific utilities |
| 73 | +``` |
| 74 | + |
| 75 | +## Code Standards |
| 76 | + |
| 77 | +### TypeScript |
| 78 | +- **Strict mode enabled** - All TypeScript strict checks are enforced |
| 79 | +- **Type-first approach** - Define types before implementation |
| 80 | +- **Absolute imports** - Use `@/` prefix for all src imports (e.g., `@/components/ui/button`) |
| 81 | + |
| 82 | +### Code Style |
| 83 | +- **ESLint + Prettier** configured for consistent formatting |
| 84 | +- **Kebab-case** for file and folder names |
| 85 | +- **PascalCase** for React components |
| 86 | +- **camelCase** for functions and variables |
| 87 | + |
| 88 | +### Architecture Rules |
| 89 | +- **No cross-feature imports** - Features should not import from each other |
| 90 | +- **Unidirectional flow** - Code flows: shared → features → app |
| 91 | +- **Colocation** - Keep related code as close as possible to where it's used |
| 92 | + |
| 93 | +## Component Guidelines |
| 94 | + |
| 95 | +### Best Practices |
| 96 | +- **Composition over props** - Use children/slots instead of many props |
| 97 | +- **Single responsibility** - Each component should have one clear purpose |
| 98 | +- **Extract render functions** - Move complex JSX into separate components |
| 99 | +- **Limit prop count** - Consider composition if accepting too many props |
| 100 | + |
| 101 | +### Styling |
| 102 | +- **Tailwind CSS** is the primary styling solution |
| 103 | +- **Headless UI components** using Radix UI primitives |
| 104 | +- **ShadCN/UI pattern** - Components are copied into codebase, not installed as packages |
| 105 | + |
| 106 | +## State Management Strategy |
| 107 | + |
| 108 | +### Component State |
| 109 | +- Use `useState` for simple independent state |
| 110 | +- Use `useReducer` for complex state with multiple related updates |
| 111 | + |
| 112 | +### Application State |
| 113 | +- **Zustand** for global application state (modals, notifications, themes) |
| 114 | +- Keep state as close to usage as possible |
| 115 | +- Avoid premature globalization |
| 116 | + |
| 117 | +### Server State |
| 118 | +- **React Query (TanStack Query)** for all server state management |
| 119 | +- **MSW (Mock Service Worker)** for API mocking during development |
| 120 | +- Separate fetcher functions from hooks |
| 121 | + |
| 122 | +### Form State |
| 123 | +- **React Hook Form** for form management |
| 124 | +- **Zod** for form validation schemas |
| 125 | +- Create reusable Form and Input components |
| 126 | + |
| 127 | +## API Layer |
| 128 | + |
| 129 | +### Structure |
| 130 | +Each API endpoint should have: |
| 131 | +1. **Types & validation schemas** for request/response |
| 132 | +2. **Fetcher function** using configured API client |
| 133 | +3. **React Query hook** for data fetching/caching |
| 134 | + |
| 135 | +### Example Pattern |
| 136 | +```typescript |
| 137 | +// api/get-discussions.ts |
| 138 | +export const getDiscussions = (params: GetDiscussionsParams): Promise<Discussion[]> => { |
| 139 | + return api.get('/discussions', { params }); |
| 140 | +}; |
| 141 | + |
| 142 | +export const useDiscussions = (params: GetDiscussionsParams) => { |
| 143 | + return useQuery({ |
| 144 | + queryKey: ['discussions', params], |
| 145 | + queryFn: () => getDiscussions(params), |
| 146 | + }); |
| 147 | +}; |
| 148 | +``` |
| 149 | + |
| 150 | +## Testing Strategy |
| 151 | + |
| 152 | +### Testing Pyramid |
| 153 | +1. **Integration Tests** (primary focus) - Test feature workflows |
| 154 | +2. **Unit Tests** - Test shared utilities and complex logic |
| 155 | +3. **E2E Tests** - Test critical user journeys |
| 156 | + |
| 157 | +### Tools |
| 158 | +- **Vitest** - Test runner (Jest-compatible but faster) |
| 159 | +- **Testing Library** - Component testing utilities |
| 160 | +- **Playwright** - E2E testing framework |
| 161 | +- **MSW** - API mocking for tests |
| 162 | + |
| 163 | +### Testing Patterns |
| 164 | +- Test behavior, not implementation details |
| 165 | +- Use real HTTP requests with MSW instead of mocking fetch |
| 166 | +- Focus on user interactions and outcomes |
| 167 | + |
| 168 | +## Security Considerations |
| 169 | + |
| 170 | +### Authentication |
| 171 | +- **JWT tokens** stored in HttpOnly cookies (preferred) or localStorage |
| 172 | +- **React Query Auth** for user state management |
| 173 | +- Automatic token refresh handling |
| 174 | + |
| 175 | +### Authorization |
| 176 | +- **RBAC** (Role-Based Access Control) for basic permissions |
| 177 | +- **PBAC** (Permission-Based Access Control) for granular control |
| 178 | +- Client-side authorization for UX (always validate server-side) |
| 179 | + |
| 180 | +### XSS Prevention |
| 181 | +- **Sanitize all user inputs** before rendering |
| 182 | +- Use DOMPurify for HTML content sanitization |
| 183 | +- Validate and escape data at boundaries |
| 184 | + |
| 185 | +## Performance Optimization |
| 186 | + |
| 187 | +### Code Splitting |
| 188 | +- **Route-level splitting** - Lazy load pages/routes |
| 189 | +- Avoid excessive splitting (balance requests vs. bundle size) |
| 190 | + |
| 191 | +### React Optimizations |
| 192 | +- **Children prop pattern** - Prevent unnecessary re-renders |
| 193 | +- **State colocation** - Keep state close to where it's used |
| 194 | +- **State initializer functions** - For expensive initial computations |
| 195 | + |
| 196 | +### Image Optimization |
| 197 | +- Lazy loading for images outside viewport |
| 198 | +- Modern formats (WebP) with fallbacks |
| 199 | +- Responsive images using srcset |
| 200 | + |
| 201 | +## Error Handling |
| 202 | + |
| 203 | +### API Errors |
| 204 | +- Global error interceptor in API client |
| 205 | +- Automatic error notifications via toast system |
| 206 | +- Automatic token refresh on 401 errors |
| 207 | + |
| 208 | +### Application Errors |
| 209 | +- **Error Boundaries** at feature level (not just app level) |
| 210 | +- **Sentry** integration for production error tracking |
| 211 | +- Graceful fallbacks for broken components |
| 212 | + |
| 213 | +## Build and Deployment |
| 214 | + |
| 215 | +### Development |
| 216 | +- **Vite** for fast development builds and HMR |
| 217 | +- **TypeScript** strict mode for compile-time safety |
| 218 | +- **ESLint + Prettier** for code quality |
| 219 | + |
| 220 | +### Production |
| 221 | +- Deploy to CDN platforms: **Vercel**, **Netlify**, or **AWS CloudFront** |
| 222 | +- Source maps uploaded to Sentry for error tracking |
| 223 | +- Environment-specific configuration via env files |
| 224 | + |
| 225 | +## File Naming Conventions |
| 226 | + |
| 227 | +- **Components**: `kebab-case.tsx` (e.g., `user-profile.tsx`) |
| 228 | +- **Hooks**: `use-kebab-case.ts` (e.g., `use-discussions.ts`) |
| 229 | +- **Utilities**: `kebab-case.ts` (e.g., `format-date.ts`) |
| 230 | +- **Types**: `kebab-case.ts` (e.g., `api-types.ts`) |
| 231 | +- **Folders**: `kebab-case` throughout |
| 232 | + |
| 233 | +## Development Workflow |
| 234 | + |
| 235 | +### Git Hooks (Husky) |
| 236 | +- **Pre-commit**: ESLint, Prettier, TypeScript check |
| 237 | +- **Pre-push**: Run test suite |
| 238 | +- Ensure all checks pass before allowing commits |
| 239 | + |
| 240 | +### Code Generation |
| 241 | +- **Plop.js** generators for consistent component creation |
| 242 | +- Templates include component, stories, and test files |
| 243 | +- Maintains consistent structure across team |
| 244 | + |
| 245 | +## Key Libraries |
| 246 | + |
| 247 | +### Core |
| 248 | +- **React 18** with concurrent features |
| 249 | +- **TypeScript** in strict mode |
| 250 | +- **Vite** or **Next.js** for build tooling |
| 251 | + |
| 252 | +### UI & Styling |
| 253 | +- **Tailwind CSS** for styling |
| 254 | +- **Radix UI** for headless components |
| 255 | +- **Lucide React** for icons |
| 256 | + |
| 257 | +### Data & State |
| 258 | +- **TanStack Query** for server state |
| 259 | +- **Zustand** for client state |
| 260 | +- **React Hook Form + Zod** for forms |
| 261 | + |
| 262 | +### Testing & Development |
| 263 | +- **Vitest** for unit/integration tests |
| 264 | +- **Playwright** for E2E tests |
| 265 | +- **MSW** for API mocking |
| 266 | +- **Storybook** for component development |
| 267 | + |
| 268 | +## Common Patterns |
| 269 | + |
| 270 | +### Feature Development |
| 271 | +1. Start with API types and validation schemas |
| 272 | +2. Create API fetcher functions and React Query hooks |
| 273 | +3. Build UI components with proper TypeScript integration |
| 274 | +4. Add integration tests covering the feature workflow |
| 275 | +5. Update routing and navigation as needed |
| 276 | + |
| 277 | +### Component Creation |
| 278 | +1. Use Plop generator: `yarn generate:component` |
| 279 | +2. Follow composition patterns over prop drilling |
| 280 | +3. Add Storybook stories for complex components |
| 281 | +4. Include unit tests for components with logic |
| 282 | + |
| 283 | +### State Management |
| 284 | +1. Start with local component state |
| 285 | +2. Lift to parent component if needed by siblings |
| 286 | +3. Move to global state only if needed across features |
| 287 | +4. Use React Query for all server state |
| 288 | + |
| 289 | +This architecture prioritizes developer experience, maintainability, and scalability while following React and JavaScript best practices. |
0 commit comments