Start with intent revealing names
Readable code is intentional code. Before touching the keyboard, decide on the story your function or component should tell. Naming aligned with that story prevents the maze of `handleData` and `processItem` functions that age poorly.
A good heuristic: if a teammate can infer the shape of the returned data or the side effects just from the signature, you are already winning.
- Prefer domain vocabulary over internal shorthand.
- Cut down the number of branches per function to keep intent focused.
- Encoder/decoder utilities deserve dedicated modules—never bury them in components.
Lean on architecture cues
Framework conventions exist to make folders navigable at 2 a.m. Respecting those conventions is half of readability. In a Next.js codebase, reserve `app/` for routes, `components/` for slices, and give utilities a home like `lib/`.
Every deviation is a cognitive tax. Document the few that remain in a `DECISIONS.md` so future hires understand the why.
Leave breadcrumbs in comments
Readable code answers the next developer's question before they ask it. A concise comment describing *why* a trade-off was made beats a verbose play-by-play of *what* the code already shows.
Pair comments with links to architectural decision records or tickets so the institutional memory lives on after the meeting notes disappear.