Frontend architecture: micro-frontends, BFF and rendering
The backend has had its styles, quanta and team boundaries for years; the frontend often stays one big application that every team edits. As products grow, the same questions arrive at the browser: who owns which part of the page, how pieces are deployed independently, which server shapes the data for which client, and where the page is rendered. This module covers the styles and decisions that answer them.
1. The idea
Micro-frontends
A micro-frontend is a part of the user interface owned end to end by one team, built and deployed independently, and combined with others into one product. It's the microservices idea (Module 16) applied to the frontend, usually so each slice of the page lines up with a bounded context (Module 08a) and a team (Module 09a). Composition can happen at three moments:
| Composition | How | Trade-off |
|---|---|---|
| Build time | Each team publishes a package; the shell app imports them and is built and deployed as one | Simple and fast at runtime, but every change ships through one release: little independence |
| Server side or edge | The server assembles HTML fragments from teams' services (server-side includes, edge workers) | Fast first paint and independent deploys; caching and error handling per fragment |
| Client side (runtime) | The browser loads each team's bundle at runtime (module federation, web components, an app shell with routing) | Full deploy independence; risk of duplicated libraries, larger downloads and inconsistent UI |
Backend for frontend (BFF)
A BFF is a server-side component dedicated to one client experience (the web app, the iOS app, a partner integration), owned by the team that builds that client. It calls the general-purpose services, combines and trims their answers, and returns exactly what that screen needs. Sam Newman described the pattern; it differs from one general API gateway (Module 21) in that each client's team controls its own.
Where the page is rendered
| Strategy | What happens | Good for |
|---|---|---|
| Client-side rendering (CSR) | The browser downloads JavaScript that builds the page | App-like products behind a login |
| Server-side rendering (SSR) | The server builds HTML per request; the browser then makes it interactive (hydration) | Personalised pages that must be fast and indexable |
| Static generation (SSG) | HTML built ahead of time and served from a CDN | Content that changes rarely: docs, marketing, blogs |
| Incremental and islands | Static pages regenerated on a schedule; or mostly static HTML with small interactive "islands" | Large content sites with some interactivity |
2. How it works
One product page, three teams
An online shop's product page has a product area (catalogue team), a "buy" box (checkout team) and recommendations (personalisation team). Watch the page assembled at the edge and each fragment get its data from its own BFF.
3. Try it yourself
Do you need micro-frontends?
Answer five questions about a product. The recommendation follows the questions that matter most: how many teams, and whether they're blocked by one release.
Pick a rendering strategy
4. Trade-offs
Independence vs consistency
Independent teams ship faster; users see a patchwork unless a shared design system and agreed rules (fonts, navigation, accessibility) hold the page together.
Autonomy vs page weight
Runtime composition lets each team pick versions; the browser may then download two copies of a framework. Share a few core libraries deliberately, as singletons.
One BFF per client vs duplication
Each client gets exactly what it needs and its team moves alone, at the cost of similar logic in several BFFs. Push shared rules down into services, not sideways between BFFs.
Server rendering vs cost
SSR improves first paint and SEO and adds servers to run, scale and secure. Static and cached output is cheapest; personalised SSR is most expensive.
5. In real projects
Start with a modular frontend, not micro-frontends. One repository, one deployment, clear module boundaries by domain and enforced import rules (a fitness function, Module 26). Split into separately deployed micro-frontends when several teams are genuinely blocked by one release train.
Split vertically, by business capability (search, product, checkout, account), never horizontally by technical layer (a "components team" and a "pages team").
Contracts between fragments are small and explicit: URL routes, custom events in the browser, and the data each fragment loads for itself. Avoid shared global state across teams' code.
A design system is architecture. Shared components, tokens and accessibility rules, versioned and owned by a team, are what make independently built pieces feel like one product.
Measure what users feel: Core Web Vitals (loading, responsiveness, layout stability) per page and per fragment, so one team's heavy bundle shows up as that team's problem.
Say it in the interview
- "Should we use micro-frontends?" Only if several teams are blocked by one frontend release and the product splits cleanly by business area; otherwise a modular monolith frontend gives most of the benefit at a fraction of the cost.
- "Why a BFF instead of one API?" Each client needs differently shaped data and changes at its own pace; a BFF per client, owned by that client's team, avoids one API bent to fit everyone.
- "SSR or a single-page app?" Public, indexable, first-impression pages benefit from server or static rendering; a logged-in, app-like tool is fine rendered on the client.
- Micro-frontends for a product with one or two teams.
- Splitting by technical layer rather than business capability.
- No plan for a shared design system, performance budget or shared dependencies.
6. Remember it
How this hook works: what "one storefront, many departments" means
What the slogan means, phrase by phrase
- "One storefront"
- A single, consistent product for the user: one shell, one design system, one navigation.
- "many departments"
- Vertical slices of the UI, each owned, built and deployed by one team, aligned with a business capability.
Why this picture fits: a department store succeeds only if departments are independent behind the scenes and indistinguishable in style at the front.
The story → the concept
| The store | The frontend |
|---|---|
| The entrance and signage | The app shell and design system |
| A department | A micro-frontend owned by one team |
| The department's stockroom | Its backend for frontend |
| House style rules | Shared tokens, components and accessibility rules |
The trap it saves you from
A "shop" where every department has its own entrance, checkout and fonts: independent teams, unusable product.
7. Common mistakes
8. Design exercise (30 minutes)
- Map the page (10 min). Take a product you know (an online shop, a bank app). Mark each area of its main page with the business capability and team that should own it.
- Choose composition (10 min). Build time, server side or client side? Justify it with the team count and how often each part changes.
- Draw the BFFs (10 min). Which clients exist? Draw one BFF per client and the services each calls.
9. Self-check quiz
When are micro-frontends worth their cost?
What is a backend for frontend?
How should a frontend be split between teams?
A documentation site changes a few times a day. Which rendering strategy fits best?
10. Go deeper
| Resource | Time | Why |
|---|---|---|
| Micro Frontends (Cam Jackson, martinfowler.com) | 45 min | Benefits, composition approaches and the costs, with an example. |
| Backends For Frontends (Sam Newman) | 20 min | The pattern from the person who named it. |
| Rendering on the Web (web.dev) | 30 min | CSR, SSR, static and hydration compared. |
| Module Federation | reference | Runtime composition of independently built bundles. |