Frontend Platform Architecture
This page covers the layers above a single frontend application: system decomposition, the edge/integration layer, infrastructure and delivery, the design system, and AI-integrated frontend patterns.
For everything inside one application — rendering strategy, state, data fetching, collaboration, access control, performance, offline, and testing — see Frontend System Architecture.
Layered View
L0 Organizing principles Conway's law · vertical slices · verification time
L1 System decomposition micro-frontends + shell · microservices · monorepo ← this page
L2 Infrastructure & delivery containers · load balancing · CDN · hosting ← this page
L3 Application internals rendering · state · collaboration · access · offline ← system-architecture.mdx
L4 Implementation / APIs useState · debounce · SSE · error boundaries ← system-architecture.mdx
Architecture Overview
0 Design Principles
├─ Conway's law → vertical slices, small teams
├─ Two-pizza team → the one-pizza team in the AI era
└─ AI drives implementation time toward zero, but raises verification time
Goal: shorten verification, shrink bug blast radius, reduce architectural drift
1 System Decomposition
├─ 1.1 Problems with the frontend monolith
├─ 1.2 Microservices (backend context)
├─ 1.3 Micro-frontends + Shell
├─ 1.4 Vertical Slice
└─ 1.5 Monorepo
2 Edge & Integration
├─ 2.1 API Gateway
├─ 2.2 Backend for Frontend (BFF)
└─ 2.3 Aggregation shape (GraphQL / purpose-built REST)
└─ (calling external services from the frontend → system-architecture.mdx §1.3)
3 Infrastructure & Delivery
├─ 3.1 Containers & Orchestration
├─ 3.2 Load Balancing
├─ 3.3 CDN & Edge Delivery
└─ (hosting options → system-architecture.mdx §1.2)
4 Design System & Styling
├─ 4.1 Design Tokens
├─ 4.2 Shared Component Library
├─ 4.3 CSS Architecture (Atomic CSS / Tailwind)
└─ 4.4 Design-to-Code MCP
5 AI-Integrated Frontend
├─ 5.1 AI-Assisted Development
└─ 5.2 MCP-UI (LLM-rendered UI)
0. Design Principles
Conway's law. A system's architecture ends up mirroring the communication structure of the organization that builds it. If the goal is small, independent teams, the system has to be split into small, independent vertical slices — otherwise coordination overhead grows until releases stall.
Team size. The "two-pizza team" (5–9 people) shrinks further with coding agents: the same output needs fewer people. The practical unit trends toward a vertically integrated engineer — one person working across the full stack with an agent.
Verification over implementation. Coding agents push implementation time toward zero but increase the time spent verifying changes. The architectural goal shifts from "ship fast" to "build a system that is cheap to verify": smaller, localized changes; a smaller blast radius for production bugs; less context needed per change; minimal architectural drift. Micro-frontends, microservices, and a monorepo all serve this goal.
1. System Decomposition
A frontend typically starts as a monolith and stays one while features accumulate. It stops scaling when too many people push code to the same client: one mistake or one global CSS change affects everyone, and coordination between contributors becomes the bottleneck.
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Team & code scaling | How should a large frontend org avoid one shared codebase? | Many teams push to the same client; global-CSS risk and coordination block releases. | Split into independently deployable frontends | Header, catalog, and checkout owned by separate teams |
| Composition | How should independent frontends form one product? | Separately deployed frontends still share auth, routing, locale, and global state. | Micro-frontend shell / host application | Shell loads header, catalog, and cart apps at runtime and passes down global state |
| Service alignment | How should a frontend map to backend ownership? | A feature needs end-to-end ownership without cross-team handoffs. | Vertical slice — one micro-frontend and its microservices, one team | One team owns the checkout UI and its payment services |
| Backend context | Why is the backend already split? | Backend modules deploy independently and communicate only through APIs. | Microservices (API + business logic + persistence per unit) | Separate pricing, inventory, and order services |
| Repository layout | How should many apps share standards and tooling? | Independent repos drift in lint config, dependencies, and code style. | Monorepo with shared tooling | One build command builds every app; a shared design-system package; agents change code across boundaries in one session |
2. Edge & Integration
Between the micro-frontends and the backend services sits repetitive, cross-cutting request handling. Centralizing it keeps individual services and individual clients simple.
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| API Gateway | Where should cross-cutting request concerns live? | HTTPS, auth, rate limiting, caching, and content negotiation are otherwise re-implemented per service. | API gateway in front of backend services | One HTTPS/auth entry point; HTTP between the gateway and services inside the VPC |
| Backend for Frontend | How should a client avoid calling many services directly? | Each client needs differently shaped data; direct calls cause over- or under-fetching. | Dedicated BFF per client, owned by the frontend team | Separate desktop and mobile BFFs over the same services |
| Aggregation shape | How should the BFF expose data to the UI? | The UI needs to select fields and combine resources in one request. | GraphQL or purpose-built REST endpoints | One request returns product, price, and reviews for a page |
| Feature ownership | Who ships UI-driven backend changes? | The frontend team should not wait on a service team's backlog for a small field. | Frontend-owned BFF acting as the client's backend | Frontend team adds a response field the new UI needs |
Calling third-party providers and proxying secret-bearing requests are covered in Frontend System Architecture §1.3.
3. Infrastructure & Delivery
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Packaging | How should services with different runtimes deploy uniformly? | Apps mix Node, Python, Next.js, and Vue runtimes and dependencies. | Docker images bundling code, runtime, and OS | Any host running Docker runs the frontend image with no runtime setup |
| Orchestration | How should many containers run reliably? | Containers need scaling, restarts, and traffic distribution. | Container orchestration — Kubernetes or ECS | Rolling deploys and self-healing for frontend and BFF containers |
| Load balancing | How should traffic exceed one server's capacity? | A single instance cannot serve peak concurrent requests. | Identical instances behind an application load balancer | Node servers behind an AWS/GCP load balancer or Nginx |
| Edge delivery | How should static assets reach a global audience fast? | Round trips to one origin add unavoidable latency (speed of light). | CDN with edge caching, compression, and cache busting | Content-hashed JS/CSS served from the nearest edge location; server push invalidates the cache |
Hosting models (static, managed, virtual servers) are covered in Frontend System Architecture §1.2.
4. Design System & Styling
Independent feature teams drift into visual divergence and duplicated code — a button on the product page ends up different from the one on the checkout page. A design system applies the DRY principle at the architecture level and gives coding agents a fixed set of constraints, which keeps their output consistent across sessions.
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Design tokens | How should visual decisions stay consistent across frontends? | Independent teams diverge on color, spacing, and type. | Design tokens as global CSS custom properties | Tokens defined in the shell, consumed by every micro-frontend |
| Shared components | How should UI code avoid duplication across teams? | Buttons, inputs, and layouts are re-implemented per frontend. | Versioned component-library package | Product and checkout apps import the same components |
| Accessibility & testing | Where should a11y and UI guarantees be centralized? | Every team otherwise re-solves focus, ARIA, and keyboard support. | Accessibility and unit tests built into shared components | Audited components reused everywhere |
| CSS architecture | How should tokens map to styling in code? | Teams need a predictable, low-conflict styling approach. | Atomic CSS generated from tokens (Tailwind is an Atomic CSS implementation) | Utility classes derived from the token set |
| Design-to-code | How should designs become components quickly? | Designers keep the source of truth in a design tool. | Design-tool MCP server driving a coding agent | Assemble a feature from Figma via an MCP server in Claude Code / Codex |
5. AI-Integrated Frontend
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Development workflow | How should coding agents produce consistent UI? | Agents invent styles and drift without shared constraints. | Extract a design system first, then feed it to the agent across sessions | Consistent component output over many agent sessions |
| Agent context | How should agents change code across service boundaries? | Cross-repo changes need full context in one session. | Monorepo plus MCP servers for design and data sources | Extract a reusable component into the design system in one pass |
| LLM-rendered UI | How should an LLM answer with interactive components, not just text? | A chat response needs to render products, maps, or forms and collect input. | MCP-UI — the server describes a UI resource; the frontend parses the tool response and renders it | Venue-search results rendered as cards and a map inside a chat |
| Streaming transport | How should the client receive incremental model output? | The server streams many tokens; the client sends one prompt (asymmetric). | Server-Sent Events | Token-by-token chat responses; the transport most LLM apps use |
Polling, SSE, and WebSockets are compared as general real-time options in Frontend System Architecture §1.5.