A Model/API Layering Architecture for React and TypeScript Projects
Scattered fetch calls and untyped props are the fastest way to turn a React codebase into a maintenance tax. A model/api/components split with strict TypeScript types removes guesswork from data flow and makes API changes a one-file operation, which pays off the moment a second developer joins or a backend contract changes.
A model/api/components layering scheme, demonstrated through a React color picker, treats TypeScript interfaces as the constitution for all frontend data. The model layer defines what data the UI needs—not what the backend happens to return—while the API layer wraps every endpoint behind a typed function so components never touch raw fetch calls or untyped responses. Components become pure consumers of typed props, with state lifted to a parent and updated through callbacks, producing a unidirectional data flow that is legible even as the project grows.
Concrete patterns include using an IIFE inside useEffect for async data loading, spreading old state for immutable updates in controlled components, and typing inline styles as React.CSSProperties to catch misspelled property names at compile time. The directory structure itself encodes the architecture: model/, api/, and components/ tell a new developer exactly where to find or place code.
The argument is that these habits are best internalized on small projects, where the overhead is negligible but the template becomes immediately reusable for larger work.
The model layer is defined by what the frontend needs, not by what the backend returns; the API layer is where any field-name mismatch gets resolved.
Passing a useState setter directly as a callback works cleanly when its signature matches the expected handler, eliminating wrapper functions.
Small projects are the ideal place to drill architectural habits because the overhead is trivial but the template becomes a reusable starting point for larger work.