- Use terminal-driven development with explicit command output.
- Iterate in short loops: implement -> lint -> typecheck -> test.
- Keep diffs small and tied to observable behavior.
pnpm lintpnpm typecheckpnpm vitest runpnpm test -- --watch=falsewhen Vitest script is absent.pnpm -s exec prettier -w .for formatting updates.
- Use functional components and strict TypeScript throughout.
- Prefer explicit props typing and narrow component contracts.
- Avoid class components and opaque abstraction layers.
- Use React 19 APIs (
use,useOptimistic,useActionState) with intent.
- Extract reusable logic into focused custom hooks.
- Keep side effects in
useEffectonly for external synchronization. - Favor derived state over duplicated mutable state.
- Model async state transitions explicitly to avoid UI ambiguity.
- Keep components single-purpose and composition-friendly.
- Prefer semantic HTML and accessible form/control patterns.
- Use project-standard styling approach consistently (Tailwind/CSS Modules/etc).
- Keep visual states clear for loading, empty, success, and error cases.
- Use Vitest with React Testing Library for component behavior tests.
- Query by role, label, and visible text before test IDs.
- Assert user-visible outcomes, not hook internals.
- Cover interaction paths, edge states, and error handling.
- Lint, typecheck, and tests must pass for touched scope.
- Add or update tests alongside behavior changes.
- Preserve readability and maintainability over cleverness.