Building Software

Engineering Fundamentals for the Agent Era

Contents Section 6, Design

Frontend and Backend

Mistakes to catch in review

  1. Authorization, pricing or discount logic enforced only in the browser, where any user can change it.

  2. Clickable divs with no keyboard handler or label, so the interface cannot be used from a keyboard or a screen reader.

  3. A screen with no loading, empty or error state, which shows a blank page or an endless spinner when anything goes wrong.

  4. Client and server validation that disagree, so a form accepts input the server rejects or rejects input the server would accept.

Splitting responsibility between the user interface and the server: where state lives, where checks run, and how the two talk.

Topics

The Untrusted Client
Everything in a browser or app can be read and changed by its user, so every rule that matters is enforced on the server.
Where State Lives
Server state, client state, URL state and caches, with a single source of truth for each value.
Rendering Models
Server-rendered, client-rendered and hybrid pages, and what each costs in speed, search visibility and complexity.
UI States
Treating each screen as a state machine with loading, empty, error, partial and success states.
Accessibility
Semantic markup, keyboard navigation, contrast and screen-reader support, so the interface works for everyone.
APIs Shaped for Interfaces
Designing server responses around what screens need, avoiding both over-fetching and chatty clients.

You understand it when you can

  • List which checks for a given form must run on the server, and explain why client-side checks are only a convenience.
  • Enumerate every state a screen can be in and say what the user should see in each one.
  • Explain where a given piece of state should live (server, client, URL or cache) and what goes wrong if it lives somewhere else.

Drill

An agent built a checkout page that computes the discounted price in the browser and posts the final amount to the server, and it hides the refund button from users who are not admins. Find how a user pays less than the listed price and how a non-admin issues a refund.

Start here

Watch

"Making Impossible States Impossible" by Richard Feldman

Richard Feldman, 2016. 25-minute talk.

Shows how to model a screen's state as an explicit union of loading, error, empty and success cases, so a blank page or endless spinner cannot be represented. The ideas carry over to TypeScript discriminated unions.

React for Two Computers | Dan Abramov

Dan Abramov, 2024. 29-minute talk.

Builds up, from first principles, the split between code that runs on the server and code that runs in the browser, and what data crosses between them. This is the mental model behind deciding where logic and state live.

Read

Web Application Security: Exploitation and Countermeasures for Modern Web Applications

Andrew Hoffman, 2024, 2nd edition.

Walks through recon, attack and defense for modern web apps, including server-side rendering and GraphQL. It shows why browser-side authorization and embedded secrets are exposed to anyone with devtools.

Form Design Patterns

Adam Silver, 2018.

Builds real forms (checkout, login, upload) accessibly, with detailed guidance on validation and error messages. This matters when client-side checks must match what the server will accept.

Primary sources