A full-stack demo using an Nx monorepo with Angular (zoneless, signals) and a .NET 10.0 Web API backend. Deployed to Azure App Service with automated PR preview deployments via Azure Static Web Apps.
- Authentication — register, login, and logout with JWT bearer tokens backed by ASP.NET Core Identity
- Notification center — persistent notification panel with unread count, mark-as-read, dismiss, and action support (e.g. one-click reload on SW update)
- PWA / service worker — offline support; notifies users when a new app version is available with an in-app prompt to reload
- Markdown content pages — Analog.js content feature renders pages from Markdown files with frontmatter support (see the About page for a live demo)
- Counter micro frontend — the Counter feature runs as a separate Module Federation remote (
counter-remote), demonstrating micro-frontend architecture with shared singleton libraries - Debug page (
/debug) — trigger test notifications and inspect service worker update state during development - PR preview deployments — every pull request gets a live preview URL via Azure Static Web Apps
Frontend
- Angular 21 — zoneless change detection, standalone components, signals
- NgRx Signal Store — reactive state management
- Angular Material — UI component library
- Analog.js — Vite-native Angular meta-framework; used for file-based Markdown content pages
- Tailwind CSS v4 — utility-first styling
- Angular PWA — service worker & offline support
- Module Federation (
@module-federation/vite) — micro-frontend architecture
Backend
- .NET 10.0 Web API
- ASP.NET Core Identity — bearer token authentication
- Entity Framework Core with Azure SQL
Tooling
- Nx — monorepo build system with affected commands
- Vitest — unit tests with ~93% line coverage
- Playwright — end-to-end tests
- Husky + lint-staged — pre-commit hooks for linting, formatting, and keeping
home.mdin sync - pnpm — package manager
Live demo: https://angularclinetcorengrxstarter.azurewebsites.net/
Prerequisites
- Node 24.x+ with pnpm 10+
- .NET SDK 10.0.x — download
Install dependencies
pnpm installpnpm startStarts both the .NET API and Angular app in dev mode. Open http://localhost:4200 for the app, or https://localhost:60254/swagger for the API docs.
The Counter feature is a Module Federation micro-frontend remote. To develop with the MFE active, start both servers in separate terminals:
# Terminal 1 — remote (port 4201)
pnpm nx serve counter-remote
# Terminal 2 — host (port 4200)
pnpm nx serve web-appThe host at http://localhost:4200 will load the Counter remote automatically from http://localhost:4201/remoteEntry.js when you navigate to /mfe-counter.
| App | Role | Port | Description |
|---|---|---|---|
web-app |
MFE host | 4200 | Main application shell |
counter-remote |
MFE remote | 4201 | Counter feature exposed via Module Federation |
Shared singletons — Angular core, CDK/Material, and NgRx are configured as Module Federation singletons so both apps share a single instance. This prevents Angular's NG0912 component-ID collision warnings that occur when the same component class is registered twice.
Remote self-containment — workspace libs (@myorg/shared, @myorg/counter) are NOT in the MF shared config because Rolldown's static analysis cannot enumerate export * chains from TypeScript path aliases. Instead, the remote is designed to be self-contained: counter-remote bundles only @myorg/counter (which has no @myorg/shared dependencies), and the host bundles @myorg/shared exclusively (no duplicate registrations).
Preview deployments — in CI, counter-remote is built and served from /counter-remote/ within the same Static Web App as the host. The COUNTER_REMOTE_ENTRY environment variable is set to /counter-remote/remoteEntry.js during the host build so the baked-in import map points to the co-deployed remote instead of localhost.
pnpm lintpnpm testCoverage requires dotnet-coverage:
dotnet tool install --global dotnet-coveragepnpm e2epnpm build:prodBuilds the Angular app and publishes the .NET project to /dist, ready to deploy to Azure App Service.
apps/web-app/src/assets/home.md is auto-generated from this file — edit README.md only. The lint-staged hook regenerates home.md automatically whenever README.md is committed.