5. Best Practices, Tooling & Capstone
Goal for this page: take your working-but-messy practice app and make it look like something a professional team would maintain — then prove it with a capstone.
Step 5.1 — DRY, the AquaGen layering & naming
What & why: As apps grow, organization is what keeps them workable. DRY ("Don't Repeat Yourself") means one source of truth for each piece of logic. You've been building the pieces across pages 3–4 — now make DevDirectory's structure match the four layers every AquaGen feature library uses, so the habit is second nature before you open the real repo.
Learn:
- DRY principle (Wikipedia)
- React: Thinking in React (how to break a UI into components)
- React: Choosing the State Structure
Your task: Make sure DevDirectory is organized into the four layers, plus a hooks/ folder:
src/
dataSource/ → API calls (getItems, getItem)
controller/ → logic that shapes data for the UI
store/ → shared state via React Context (FavoritesStore)
components/ → presentational UI (Card, Header, pages)
hooks/ → reusable hooks (useFetch, useDebounce)
Adopt consistent naming (components PascalCase, hooks useCamelCase, files matching their
export) and remove any duplicated code you find along the way. This is the exact shape you'll
recognize in libs/<feature>/src/ in the real codebase.
Step 5.2 — Code splitting & lazy loading
What & why: Shipping your whole app in one big bundle makes the first load slow. Code
splitting loads pages only when the user visits them, via React.lazy and Suspense.
Learn:
Your task: Convert your route components (list, detail, favorites) to be lazy-loaded
with React.lazy, wrapped in Suspense with a fallback. In DevTools' Network tab, confirm
each page's JavaScript loads only when you navigate to it.
Step 5.3 — Performance basics
What & why: Unnecessary re-renders and recomputation slow apps down. useMemo,
useCallback, and correct list keys are the everyday tools — used deliberately, not
everywhere.
Learn:
Your task: Find one expensive computation or one function passed to a memoized child in
your app and optimize it with useMemo/useCallback. Note why it helped — if you can't
explain the why, you probably didn't need it (that's a valid finding).
Step 5.4 — Code quality tooling
What & why: Linters and formatters catch bugs and end style debates automatically. This is standard on every professional team, including ours.
Learn:
Your task: Ensure ESLint runs on your project and fix its warnings. Set up Prettier and enable format on save in VS Code. Get to zero lint errors.
Step 5.5 — Git & the pull-request workflow
What & why: Professional code ships through branches and pull requests that get
reviewed — never straight to main. Small, well-described commits make review easy. This
is exactly how you'll contribute to our real repos.
Learn:
- GitHub: Git & GitHub basics
- GitHub: About branches
- GitHub: Creating a pull request
- Conventional Commits
Your task: Put DevDirectory in a Git repo and push it to GitHub. Do a small change on a
feature branch, open a pull request against your own main, write a clear
description, and merge it. You've now rehearsed our real contribution flow.
Step 5.6 — Capstone
What & why: The best proof you've learned this is building something small without a tutorial.
Your task — build a mini app from scratch that:
- fetches from a dummy API through a
dataSource/layer and shows a list + detail view (React Router,useParams); - has search/filter driven by URL query params;
- keeps shared state in a
store/(React Context) and logic in acontroller/; - uses at least one custom hook you wrote;
- lazy-loads its routes;
- is organized into the
dataSource / controller / store / componentslayering, passes ESLint/Prettier, and lives in a Git repo with at least one PR.
Share it with your onboarding buddy for feedback.
Everything above is exactly what our production frontend is built from — just at larger scale. Next, get the real app running with Installation & Setup, then take the Practice track in the Architecture section to learn how AquaGen is put together.