Architect Thinking Before Framework Thinking
Why this chapter matters
Frameworks are powerful, but they are not the architecture. They are implementation environments for decisions about users, data, latency, security, ownership, and change.
Senior engineers often ask, "Which framework feature should we use?" Architects first ask, "What constraint are we trying to satisfy?"
The decision stack
Use this order before choosing framework mechanics:
- User outcome: What must the user accomplish?
- Product constraint: What business, legal, growth, or workflow constraint matters?
- Runtime constraint: What must happen across server, edge, browser, network, and device?
- Data constraint: Who owns the data, how fresh is it, and how can it fail?
- Quality constraint: What performance, accessibility, security, and reliability bar applies?
- Team constraint: Who owns the surface and how often will it change?
- Framework mapping: Which framework capabilities best implement the decision?
Constraint inventory
Before framework discussion, inventory constraints in plain language.
| Constraint type | Questions |
|---|---|
| User | Who uses this, in what context, and what failure breaks trust? |
| Product | Is this conversion, retention, compliance, internal productivity, or discovery work? |
| Data | Who owns truth, how fresh is it, and what mutations are risky? |
| Runtime | What must happen on server, edge, browser, worker, cache, or device? |
| Interaction | What are loading, empty, pending, partial, offline, and recovery states? |
| Accessibility | What focus, keyboard, semantics, motion, contrast, and cognitive constraints apply? |
| Security/privacy | What input, identity, storage, logging, and third-party boundaries are risky? |
| Team | Who owns it, how many teams touch it, and how often will it change? |
| Operations | How will the team detect, roll back, and learn from failure? |
Example: product page
Framework-first answer:
Use SSR because it is faster.
Architect answer:
The product page is public, SEO-sensitive, mostly cacheable, and must show price and availability accurately enough for the market. Use static or cached server rendering for stable content, isolate availability freshness, hydrate only purchase controls, and measure LCP/INP separately.
Example: dashboard
Framework-first answer:
Use client components because dashboards are interactive.
Architect answer:
The dashboard has a server-rendered shell, panel-level data dependencies, client-side filters, and role-specific actions. Render the shell and stable panel chrome server-side, hydrate high-interaction regions, keep URL state separate from server state, and degrade panels independently.
Example: GenUI copilot
Framework-first answer:
Use an AI SDK to stream components.
Architect answer:
The model may propose UI from a registry, but deterministic code validates schema, enforces permissions, renders accessible components, logs failures, and falls back safely. The framework streaming API is an implementation detail behind that product contract.
Framework evaluation worksheet
| Question | Why it matters |
|---|---|
| What decision does the framework feature help implement? | Prevents feature-chasing. |
| What new coupling does it introduce? | Exposes migration and ownership cost. |
| What failure mode becomes harder to debug? | Forces operational thinking. |
| What is the rollback path? | Separates experiments from commitments. |
| Can the team explain it without one expert? | Reduces bus factor. |
| Does it improve measurable user outcomes? | Keeps architecture connected to product. |
| Which constraint becomes easier to satisfy? | Forces the proposal to connect to a real problem. |
| Which constraint becomes harder? | Makes tradeoffs explicit. |
| What is the smallest pilot? | Avoids organization-wide commitments before evidence. |
| What would make us remove it? | Defines exit criteria before sunk cost appears. |
Anti-patterns
- Choosing rendering mode globally.
- Treating server components as a security boundary by themselves.
- Using microfrontends to solve unclear ownership.
- Using GenUI before defining component contracts.
- Adding state libraries before defining state ownership.
- Adding edge logic without cache-key and observability design.
- Treating framework documentation examples as production architecture.
- Adopting a feature because it is new while the current bottleneck is product ambiguity, ownership, or observability.
- Making a global rule from one successful route.
- Ignoring hiring, debugging, and migration cost.
Decision translation example
Weak proposal:
Move this app to a new framework because it supports streaming and server functions.
Architect proposal:
The onboarding route loses users on slow mobile connections because the first useful form appears late and client-side validation code blocks interaction. The proposal is to render the shell and first step on the server, stream secondary guidance, keep validation close to the mutation boundary, and hydrate only interactive form controls. We will pilot this on onboarding step one, measure LCP, INP, submit success, validation error recovery, and support tickets, then decide whether the pattern should become a route standard.
The framework feature is present, but it is not the argument. The argument is user outcome, constraint, implementation boundary, and verification.
Exercise
Pick a framework feature your team is excited about. Write a one-page decision that does not mention the framework name until the final section.
If the decision still makes sense, the architecture is probably sound. If it collapses, the proposal was likely tool-led.