What is Piral?

You have a frontend. It works. But as it grows, the same friction keeps appearing: every release touches everything, teams block each other, upgrading a shared library breaks things in five places you didn't expect.

Piral is the framework that makes micro frontends practical rather than just theoretically appealing.

The core idea

Piral lets you compose a web application at runtime from independently deployed modules — called pilets — coordinated by a thin host called the app shell.

Your users see one application.
Your teams ship independently.

Three parts, one application

Every Piral application has the same structure:

The app shell — A small, stable host application. It provides layout, authentication, navigation, and the runtime that loads pilets. The app shell rarely changes. It is the stage.

Pilets — Self-contained feature modules. Each is an npm-like package, developed and deployed independently by a single team. A pilet registers its pages, menu items, and UI contributions into the app shell at runtime via the Pilet API.

The feed service — A small HTTP endpoint the app shell calls on startup: "which pilets should I load right now, for this user?" The feed makes runtime composition dynamic — roll out, roll back, or target pilets per user without touching the app shell.

Feed service which pilets exist App shell wires everything together Pilets — domain functionality Pilet A Pilet B Pilet C lists pilets register One application one coherent experience for the user
The feed service says which pilets exist, pilets bring the domain functionality, and the app shell wires them into one application.

What makes Piral distinct

At its core, what sets Piral apart is loose coupling. Approaches that wire micro frontends together by importing directly from one another couple them tightly — if a remote disappears or renames an export, its consumers break. Piral instead routes everything through a central engine, so pilets never depend on each other: they only assume the shell is present and interact indirectly, through extension slots and events. The features below all exist to make that loose coupling practical.

Direct imports tight coupling Piral — loose coupling MFE A MFE B MFE C a remote vanishes or an export is renamed → consumers break App shell central engine Pilet Pilet Pilet pilets depend only on the shell · talk via slots & events
Direct imports couple micro frontends — a missing remote or renamed export breaks consumers. Piral routes everything through a central engine, so pilets depend only on the shell and communicate indirectly.

The Pilet API — A versioned, TypeScript-typed contract between the app shell and every pilet. Pilets register capabilities through a well-defined interface. This makes pilets portable, safe, and introspectable.

The emulator — When you build your app shell, the CLI produces an npm package (the emulator) that pilet developers install locally. Running pilet debug renders the pilet inside the real shell, with hot reload, without any platform access. This is the single biggest developer experience improvement over other micro frontend approaches.

Distributed dependency sharing — Dependencies are not locked to the app shell. Any pilet can declare shared packages via its own importmap in package.json. If another pilet has already loaded that package, subsequent pilets reuse the same instance — no duplication, no central coordination required between teams.

Extension slots — Pilets contribute UI into each other's pages without coupling. A product pilet registers for a slot the cart pilet declares. Neither knows about the other. The shell's registry connects them.

When to use Piral

Team scaling is the best-known reason to reach for Piral, but it isn't the only one. Piral makes sense whenever an application benefits from being composed at runtime from independent modules:

  • Multiple teams need to ship features independently, on different release cadences.
  • The application is inherently dynamic — it's assembled from pieces that vary per user or tenant, come and go behind feature flags, or roll out and back without redeploying the host.
  • You want strong architectural guidelines to enforce a highly modular system with clear, contract-based boundaries — valuable even for a single team that prizes modularity.
  • You're migrating a monolith incrementally and want to extract features one at a time.
A word of caution

Piral adds operational overhead: a feed service to run, pilet packages to publish, more deployment pipelines. If you have a single small application with no need for runtime composition or hard module boundaries, a well-structured monorepo SPA may be the simpler choice. Adopt Piral when modularity, dynamism, or team independence is a genuine goal — not by default.

Technology stack

  • React for the app shell and pilet runtime (pilets themselves can use other frameworks)
  • piral-cli for debugging, building, and publishing — installed per-project, not globally (scaffold with npm init piral-instance / npm init pilet)
  • MIT licensed, fully open source
  • Actively developed and maintained by the community and smapiot

Where to go next

New here? Start with Why micro frontends? to understand the problem space, then come back and follow the Quick start.

Already convinced? Jump straight to Quick start.

Want to understand the architecture first? Go to Architecture overview.