HTML / CSS

Building a Scalable Web Application with Single-SPA and Microfrontends

At a certain scale, a monolithic frontend becomes a bottleneck. Teams step on each other. Deployments are all-or-nothing. One team's broken code blocks ev...

11 Aug 2024

Building a Scalable Web Application with Single-SPA and Microfrontends

At a certain scale, a monolithic frontend becomes a bottleneck. Teams step on each other. Deployments are all-or-nothing. One team's broken code blocks everyone else's release.

Microfrontends solve this the same way microservices solved it on the backend: break the monolith into independently deployable pieces. Single-SPA is one of the frameworks that makes this architecture work.

What Single-SPA Does

Single-SPA lets you compose multiple independent SPAs into one application. Each microfrontend can be developed, tested, and deployed on its own.

Why it works:

  • Independent deployments: One team ships without waiting for others.
  • Framework agnostic: Mix React, Vue, and Angular in the same shell. Each team picks what they know best.
  • Scalable team structure: Each microfrontend maps to a team boundary. Ownership is clear.

Why it hurts:

  • Complexity: Shared dependencies, routing coordination, and cross-app communication add overhead.
  • Bundle size: Multiple frameworks means duplicate runtime code unless you're careful with shared dependencies.
  • Debugging: Tracing a bug across microfrontend boundaries is harder than in a monolith.

The Architecture

Microfrontends follow the same idea as backend microservices. Each one owns a feature or section of the application. A root configuration ties them together.

In the project I built, the structure looks like this:

  • root-config: The shell app. Handles routing and loading of microfrontends.
  • styleguide: Shared design tokens and reusable components.
  • navbar: Owns the navigation bar.
  • utilities: Shared utility functions and services.
  • procurement: Domain-specific functionality for procurement workflows.

Managing It All With a Script

Local development with multiple microfrontends running simultaneously needs automation. I wrote a Bash script that:

  • Kills any processes on ports 9000–9010 to prevent conflicts
  • Installs dependencies for each microfrontend using pnpm
  • Starts each service in the background
  • Prints the URL to access the composed application

Without this kind of automation, you'd spend half your day starting and restarting services.

Here's the repo: https://github.com/ehsangazar/singlespa

When to Use Microfrontends

Use them when: You have multiple teams working on a large frontend. Deployment independence is worth the architectural complexity. You need to migrate incrementally from a legacy app.

Skip them when: You're a small team. You have a single product with a single deployment cadence. The coordination overhead will slow you down more than the monolith does.

Microfrontends are a scaling solution. Apply them at scale.