# Best Practices for Development This skill provides production-ready best practices for building SPA React applications. Use this guidance when implementing features, reviewing code, or making architectural decisions. ## Stack Overview - **React 19** with React Compiler (auto-memoization) - **TypeScript** (strict mode) - **Vite** (bundler) - **Biome** (formatting + linting) - **TanStack Query** (server state) - **TanStack Router** (file-based routing) - **Vitest** (testing with jsdom) - **Apidog MCP** (API spec source of truth) ## Project Structure ``` /src /app/ # App shell, providers, global styles /routes/ # TanStack Router file-based routes /components/ # Reusable, pure UI components (no data-fetch) /features/ # Feature folders (UI + hooks local to a feature) /api/ # Generated API types & client (from OpenAPI) /lib/ # Utilities (zod schemas, date, formatting, etc.) /test/ # Test utilities ``` **Key Principles:** - One responsibility per file - UI components don't fetch server data - Put queries/mutations in feature hooks - Co-locate tests next to files ## Tooling Configuration ### 1. Vite + React 19 + React Compiler ```typescript // vite.config.ts import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [ react({ babel: { // React Compiler must run first: plugins: ['babel-plugin-react-compiler'], }, }), ], }) ``` **Verify:** Check DevTools for "Memo ✨" badge on optimized components. ### 2. TypeScript (strict + bundler mode) ```json // tsconfig.json { "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "jsx": "react-jsx", "verbatimModuleSyntax": true, "isolatedModules": true, "strict": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true, "noFallthroughCasesInSwitch": true, "types": ["vite/client", "vitest"] }, "include": ["src", "vitest-setup.ts"] } ``` ### 3. Biome (formatter + linter) ```bash npx @biomejs/biome init npx @biomejs/biome check --write . ``` ```json // biome.json { "formatter": { "enabled": true, "lineWidth": 100 }, "linter": { "enabled": true, "rules": { "style": { "noUnusedVariables": "error" } } } } ``` ### 4. Environment Variables - Read via `import.meta.env` - Prefix all app-exposed vars with `VITE_` - Never place secrets in the client bundle ## Testing Setup (Vitest) ```typescript // vitest-setup.ts import '@testing-library/jest-dom/vitest' // vitest.config.ts import { defineConfig } from 'vitest/config' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], test: { environment: 'jsdom', setupFiles: ['./vitest-setup.ts'], coverage: { reporter: ['text', 'html'] } } }) ``` - Use React Testing Library for DOM assertions - Use msw for API mocks - Add `types: ["vitest", "vitest/jsdom"]` for jsdom globals ## React 19 Guidelines ### Compiler-Friendly Code - Keep components pure and props serializable - Derive values during render (don't stash in refs unnecessarily) - Keep event handlers inline unless they close over large mutable objects - Verify compiler is working (DevTools ✨) - Opt-out problematic components with `"use no memo"` while refactoring ### Actions & Forms For SPA mutations, choose one per feature: - **React 19 Actions:** `