Day 25 — Nx Monorepos: Enterprise Angular Architecture
📘 Day 25 — Nx Monorepos: Enterprise Angular Architecture
Zero to Hero — Hands-on Angular Tutorial
Today you will learn:
- ✔️ What is a Monorepo?
- ✔️ Why Nx is the industry standard for Angular.
- ✔️ Creating an Nx Workspace (
npx create-nx-workspace) - ✔️ Sharing code between apps (Libs vs Apps)
- ✔️ The concept of Effected (
nx affected:test) - ✔️ Architectural boundaries and best practices.
Most serious Angular jobs (Banking, Tech, Enterprise) do not use the standard ng new. They use Nx. 🏢
🟦 1. Why Nx?
The default Angular CLI is great for one app. But what if you have:
- Customer App (Web)
- Admin Portal (Web)
- Shared UI Library (Buttons, Inputs used by both)
- Shared Logic (Auth, Interfaces used by both)
If they are in separate repos, sharing code is a nightmare (npm link? private registry?). In a Monorepo, everything lives together, but is strictly isolated by libraries.
Nx Powers:
- Caching: If you don’t change code, Nx doesn’t re-test/re-build it. Instant builds.
- Visual Graph: See who depends on what.
🟩 2. Create an Nx Workspace
Instead of ng new, we do:
npx create-nx-workspace@latest my-org
Choices:
- Stack: Angular
- Monorepo or Standalone?: Integrated Monorepo (This is crucial to learn the structure).
- Application Name:
store-front - Bundler: Esbuild
- Test Runner: Jest/Karma
Structure:
my-org/
apps/
store-front/ (The Customer App)
store-admin/ (The Admin App)
store-api/ (Node/Target backend, optional)
libs/
ui/ (Shared Buttons/Cards)
auth/ (Shared Auth Logic)
products/ (Product Features)
nx.json
🟧 3. Creating a Shared Library
We never want to duplicate code. Let’s make a UI library.
nx g @nx/angular:library ui --directory=libs/shared/ui
This creates libs/shared/ui.
Add a Component to the Lib:
nx g @nx/angular:component header --project=shared-ui --export
Using the Lib in Apps:
In apps/store-front/src/app/app.component.ts:
// Import directly via the path alias!
import { HeaderComponent } from '@my-org/shared/ui';
@Component({
imports: [HeaderComponent],
template: `<lib-header></lib-header>`
})
export class AppComponent {}
This works because tsconfig.base.json automatically maps @my-org/shared/ui to the folder. Valid, Intellesense-supported imports!
🟥 4. Caching & “Affected” (The Magic)
Nx knows the dependency graph.
If you modify only store-admin, and run:
nx affected:test
Nx will SKIP testing store-front entirely. It saves massive time in CI/CD.
Try the Graph:
nx graph
It opens a browser window showing exactly how your apps and libs differ and connect.
🟫 5. Enterprise Architecture Rules
How do we organize code in a huge repo?
- Apps should be thin: They are just containers.
- Libs hold the logic:
- Feature Libs:
libs/products/feature-list(Smart Components) - UI Libs:
libs/shared/ui(Dumb Components) - Data Libs:
libs/products/data-access(Services, State) - Util Libs:
libs/shared/util(Date formatting, Helpers)
- Feature Libs:
- Strict Boundaries:
sharedcannot import fromproducts.uicannot import fromfeature.- (Enforced via ESLint tags
scope:shared,type:feature).
🎉 End of Day 25 — What You Learned
Today you graduated to “Architect”:
- ✔️ Nx Workspace: The home for multiple apps.
- ✔️ Apps vs Libs: Logic belongs in Libs. Apps are just shells.
- ✔️ Path Aliases: Clean imports (
@my-org/ui). - ✔️ Affected Commands: Only test what you break.
- ✔️ Dependency Graph: Visualizing your architecture.
🧪 Day 25 Challenge
“Mini-Monorepo Setup”
- Create a new Nx workspace
demo-workspace. - Generate two apps:
customer-appandadmin-app. - Generate a lib:
shared-ui. - Create a
BannerComponentinshared-ui. - Import and use the Banner in BOTH apps.
- Run
nx serve customer-appand verify. - Run
nx graphand screenshot the relationship.