Next.js is the most popular React framework for good reason. But without conventions, a Next.js codebase can become a maze of inconsistent patterns. Here's how we keep ours maintainable.
Colocate by feature, not by type
Don't put all your components in components/ and all your hooks in hooks/. Group by feature: everything related to "billing" lives together.
textsrc/ features/ billing/ components/ hooks/ utils/ billing.test.ts auth/ components/ hooks/ auth.test.ts
Testing that pays for itself
We follow a simple testing strategy:
- Unit tests for business logic and utilities
- Component tests for critical UI interactions
- E2E tests for the happy path of each core flow
The boring stuff that matters
- Use TypeScript strict mode from day one
- Enforce import ordering with ESLint
- Set up pre-commit hooks for formatting and linting
- Document architectural decisions in ADRs
Boring is a feature. If your framework choices are exciting, you're probably doing it wrong.