RTS questionnaire · Q30 · Front-end architecture proof

Have you designed front-end architectures using patterns such as Micro-frontends, modular monoliths, shared component libraries, or other architectural approaches?

A runnable review of the design work itself: which pattern I choose for which problem, the boundaries that are enforced in code rather than in a diagram, and the measurable criteria that decide whether the architecture is working.

Status: reviewed Live architecture-decision workflow Modular monolith · Design system · Monorepo · ADRs Jump to live proof ↓

30. Designing the front-end architecture

Answer as submitted

“Yes — front-end architecture design is a responsibility I have owned as a senior developer and technical lead.”
Technical decision: expand. The submitted line states the responsibility without showing a design. This page is the separate, detailed version: it shows the pattern I choose by default and why, the boundaries that are enforced in lint instead of in a diagram, the shared component library that makes the estate coherent, and the ADR log with the criteria used to judge whether the design worked.

Expanded answer

Yes, and my default answer is the least fashionable one: a modular monolith — one deployable Angular application split into enforced feature boundaries, each feature owning its routes, its state and its API access, with a deliberately small shared kernel and an import matrix that fails lint when a feature reaches into another. Micro-frontends come second, reserved for the case where independent deployment or framework heterogeneity is a genuine requirement rather than an aspiration; the mechanics are on the Q29 proof page. Across both, a shared component library and a single source of design tokens is the mechanism that keeps four applications looking like one product. Beyond those, I have used feature-sliced design to give imports a direction, an Nx-style monorepo with affected-only builds so CI stays proportional to the change, a BFF to keep the client simple, and islands with SSR only on the pages where SEO or first paint actually demands it. Every one of those choices is written up as an ADR — problem, alternatives rejected, consequences, migration path — and judged against criteria that are measured per release rather than asserted in a slide: deploy independence, build time, change failure rate, and how long a new developer takes to ship their first feature.

ApproachWhen I choose itWhat it costs
Modular monolithmost product teams: one deployable, enforced feature boundaries, lazy-loaded domainsa shared pipeline means a shared red build, so the affected-graph build is mandatory
Micro-frontendsthree or more teams, or a real framework-heterogeneity requirementduplicated runtime, version negotiation, coordination across teams
Shared component libraryalways, whichever pattern is chosen: it is what makes the estate coherenta breaking change has N consumers, so migration notes are part of the release
Monorepo with affected buildsseveral applications and libraries sharing code and toolingworkspace tooling and dependency hygiene to maintain
Feature-sliced designwhen feature folders exist but the import direction is not namedan initial refactor to place existing code in layers
BFF and islands / SSRa complex backend for the UI, or pages that must be indexablea second rendering path and another deployment to operate

Live architecture-decision workflow proof

The running component below changes its approach/result view through real event binding. Select an approach to see what it is made of, the reasoning behind choosing it, and the evidence that it was measured rather than asserted.

LIVE PREVIEW
RUNNING
ARCHITECTURE DECISION WORKFLOWRUNNING

Choose a front-end architecture approach

Select an approach to inspect what it is made of, the reasoning and the evidence.

$ apps/web → features/{orders, billing, search} → shared/kernel (one deployable; boundaries enforced by lint, not by convention)

One deployable Angular application split into enforced feature boundaries: each feature owns its routes, state and API access, lazy-loaded domains keep the initial bundle small, and the shared kernel holds only what every feature genuinely needs. It is my default because it delivers most of the benefit of modularity without the operational cost of separate deployments.

deployables: 1
cross-feature imports allowed by the import matrix: 0
new developer to first shipped feature: 3 days

What the architecture design buys

Rules I apply. Name the boundaries and then enforce them mechanically, because a boundary that only exists in a diagram disappears in the next sprint; keep the shared kernel small, since everything in it becomes a reason for every feature to be released together; make the design system the single source of tokens and behaviour so consistency is a dependency rather than a review comment; give each feature a public entry point and forbid deep imports, so a library can be versioned at all; and write the decision down as an ADR with the alternatives that were rejected, because the value of an architectural decision is in the reasoning, not in the outcome.
Boundary for Q30: this page covers the architecture-design work — choosing between patterns, enforcing the boundaries, documenting the decisions and measuring the result. The micro-frontend strategies themselves, with their runtime mechanics and shared-dependency rules, are on the Q29 proof page.

Source files

Select a file to inspect the proof with syntax highlighting and line numbers. The first file is the code running the component above; the others are the ADR log with the measured criteria, the enforced import matrix and the monorepo workspace that carries the same tags.

Acceptance criteria