Scalable Architecture and Monorepos
Architecture is the part of frontend work that does not show up in a screenshot but shows up everywhere else: in how long it takes a new engineer to ship their first meaningful change, in whether a refactor feels like a surgical edit or a game of Jenga, and in whether your CI can tell you “this broke the dashboard” or only “something failed somewhere.” For experienced TypeScript developers, the uncomfortable truth is that React scales poorly by default if you treat it as a bag of components. The runtime is forgiving; the graph of imports is not. Once a codebase crosses the threshold where no single person can hold the dependency map in working memory, structure stops being aesthetics and becomes a performance and reliability strategy.
Good architecture improves perceived performance indirectly. Features that are isolated compile and test in smaller units. Boundaries make lazy loading and code splitting obvious instead of archaeological. Shared UI stabilizes bundle churn. Monorepos let you change a type in a package and fix every consumer in one atomic commit instead of coordinating semver bumps across six repositories. None of that replaces measuring Core Web Vitals or profiling renders—but it determines whether optimization work is repeatable engineering or heroics.
This chapter connects three patterns that teams often confuse because they all sound like “scaling React”: feature-based organization inside one app, Turborepo-style monorepos across multiple apps and packages, and Module Federation 2.0 for independently deployed micro-frontends. They solve different problems. Feature folders tame complexity within a repository. Monorepos tame complexity across packages that still share ownership and release cadence. Module Federation tackles organizational boundaries so hard that teams genuinely cannot—or should not—ship from a single repo, and are willing to pay for runtime composition.
The sections that follow are deliberately opinionated. You will see explicit guidance on when not to adopt micro-frontends, when a monorepo is premature, and when layering rules deserve automated enforcement instead of team folklore. The goal is not a universal blueprint—greenfield startups and regulated enterprises rarely want the same shape—but a decision framework that matches structure to team topology.
Feature-Based Organization and Layering Rules explains why the classic components/, hooks/,
services/ split feels fine at fifty files and collapses at five hundred, then introduces the App →
Features → Shared model with import rules that prevent circularity. You will learn how each feature
exposes a deliberate public surface through barrel files, how shared/ stays boring on purpose, and
how ESLint can turn architectural intent into failing builds.
Turborepo: Monorepos for Multi-App Shared Libraries walks through the shape of a modern pnpm
workspace with Turborepo: scaffolding, packages/ui with conditional exports and peer dependencies
on React 19, shared typescript-config, and task graphs where dependsOn: ["^build"] encodes the
real dependency order. Remote caching gets a honest treatment—it is not magic, but it can collapse
redundant work across CI machines once linked.
Module Federation 2.0: Independent Micro-Frontend Deployment covers the April 2026 stable line,
multi-bundler support, dynamic TypeScript typing for remotes, the mf-manifest.json deployment
protocol, and the Host Independence Principle: the shell owns platform concerns; remotes own product
UI. The closing argument is restraint. Federation is a powerful integration technology and a poor
substitute for internal communication. If your constraint is npm package versioning, you do not have
a micro-frontend problem—you have a release process problem.
By the end of this chapter, you should be able to look at a growing React organization and name the smallest structure that fits: feature slices, monorepo packages, or runtime federation—without reaching for the heaviest tool by default.