# Luigi is a micro frontend framework built around an iframe shell

> Luigi is a JavaScript framework for administrative user interfaces that are assembled from micro frontends, with a Core application that owns routing, navigation and authorization and Client libraries that talk to it over postMessage. Its README spends more space on micro frontend security rules than on features, which tells you where the risk sits.

**luigi-project/luigi** — Micro frontend framework

- Repository: https://github.com/luigi-project/luigi
- Website: https://luigi-project.io
- Stars: 928 · Forks: 185
- Language: JavaScript
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/luigi-project-luigi

## A core application and client libraries, talking over postMessage

Luigi is described as a micro frontend JavaScript framework that enables you to create an administrative user interface driven by local and distributed views. The web application communicates with the micro frontends it contains, and the settings for routing, navigation, authorization and user experience elements are configured rather than hand-assembled per team.

The structure is two parts. Luigi consists of a Luigi Core application and Luigi Client libraries, and they establish secure communication between the core and the micro frontends using the postMessage API. The core is the shell that owns the frame, the navigation and the URL. The client is the piece a micro frontend team embeds in their own application.

The repository layout matches that split, with core/ and core-modular/ holding the shell, client/ the client library, and client-frameworks-support/ for framework integrations. There are also plugins/, a container/ directory that is published under its own version tags, a cra-template/ directory, and the website and docs folders.

The audience is clear: teams maintaining internal tools and administration panels, typically large ones where several groups own separate areas of the same interface and cannot agree on a single release cycle.

There is no installation constraint worth mentioning. The README says Luigi can run on any operating system and there are no specific requirements for installing it.

## The core owns routing, navigation and authorization in one place

The value of a micro frontend framework is not the iframe. It is the shared state that the iframes would otherwise each have to reconstruct.

According to the README, Luigi allows a web application to communicate with the micro frontends which the application contains, and you can easily configure the settings such as routing, navigation, authorization and user experience elements. So when a user navigates, the core decides which micro frontend is visible and what the URL becomes. Authorization is a core concern rather than something each micro frontend implements.

That centralisation is also the trade-off. A micro frontend that wants to change the navigation, or apply its own permission model, has to work through the core rather than acting on its own. For an organisation where the admin interface is one product with one security model, that is a benefit. For a collection of loosely related tools, it can feel like the core is in the way.

The documentation site covers installing the Core and the Client in separate guides, and the README points to a getting started guide for the structure of Luigi, the application examples in core/examples for exploring features, and the Luigi Fiddle, which is described as a place to see Luigi in action and configure a sample application. That last one matters for evaluation: you can look at a running sample without setting up an application first.

## The origin you receive at init is the trust anchor for a micro frontend

The development guidelines for micro frontend developers are the most security-relevant part of the README, and they are short enough to quote in full as a list of requirements.

Make the micro frontend accessible only through HTTPS. Add Content Security Policies. Make the Access-Control-Allow-Origin HTTP header as restrictive as possible. And maintain an allowlist with trusted domains, comparing it with the origin of the Luigi Core application, because the origin is passed when you call the init listener in your micro frontend, and processing should stop if the origin does not match.

That last point is the mechanism. The core tells the micro frontend which origin it is talking from, the micro frontend checks that against its own allowlist, and a mismatch ends the conversation instead of continuing. A micro frontend that does not implement the check is a micro frontend that will accept messages from any page that embeds it.

There is a second layer. The README notes that Luigi follows sandbox rules for iframes and links to the helper file that implements them in the core source. So the isolation model has two pieces: the browser-level sandbox attributes on the iframe, and the application-level origin check inside the frame.

The order matters for how you should evaluate a micro frontend. The guidelines are written for the people building the micro frontends, not only for the ones running the core, which tells you that the framework considers the client side to be the less trusted party.

## Testing spans unit, browser, and running old versions against your app

The test story is unusually thorough for a framework, and the third kind of test is the interesting one.

Unit tests run with npm run test in the core folder. The end-to-end tests need two applications started first, the Angular example application with npm start in its folder and the js test application with npm run dev in its folder, after which the tests are launched with npm run e2e:open for the interactive mode or npm run e2e:run for the headless browser, both from the test/e2e-test-application folder.

Then there are the backward compatibility tests. Their purpose is to ensure that applications written for previous versions of Luigi still work after Luigi is updated with npm. Before running them you bundle Luigi with npm run bundle in the main repository folder, and the script needs jq, which the README installs with brew install jq, although it can be omitted when the run is tagged latest.

```bash
npm run test:compatibility -- --tag latest
```

That last suite is the one that changes how you upgrade. A framework that can rewrite your application's routes and navigation on upgrade is only safe if something proves the old application still works. Here that proof is a script that installs a previous version, bundles it and runs your application against it, and it is wired into CI with the --install flag.

For contributors, the repository also standardises formatting. All projects use Prettier, and the npm install command in the root folder installs it along with husky, the Git hooks manager, so the formatting is applied before a commit lands.

## The container ships on its own version line

The release history tells you that Luigi is not one artefact. The framework release v2.32.0 was published on 2026-10-05, while the container directory has its own tags, container/v1.7.11 from 2026-08-13 and container/v1.7.10 from 2026-07-31.

So a consumer of Luigi tracks at least two version numbers. That is not unusual for a repository that publishes a shell, a client library and a packaged container, but it does mean that a version string in a dependency list does not tell you the whole story. The README does not explain what the container is or how its version relates to the core version, so treat the two lines as separate unless the documentation says otherwise.

The last push to the repository was on 2026-10-19, so the code moves constantly, and the presence of a CHANGELOG.md at the root is where you would look for what changed in a given release.

There is also a container/ directory with its own examples and test applications, an osv-scanner.toml at the root for dependency vulnerability scanning, and a bundle-size.js script in the package scripts, which suggests the bundle size is tracked as part of the build.

## Hand-rolled iframes versus a framework that owns the shell

The alternative is to assemble the shell yourself. An iframe, a window.postMessage listener, a hash or history based router and a permission check is not a large amount of code, and writing it gives you total control over the behaviour of your admin interface with no framework in the dependency list.

The difference in approach is what happens on upgrade and on scale. A hand-rolled integration means every team that owns a micro frontend implements its own message contract, and when the navigation model changes, each of them has to be updated by hand. A framework like Luigi centralises routing, navigation and authorization in the core and communicates over one documented channel, postMessage, and it provides the backward compatibility test that checks your application still works after the core is updated.

The cost on the other side is real. With a framework you accept its routing model, its navigation primitives and its client API, and you accept that the micro frontend runs inside a sandboxed iframe with the origin checks that implies. Luigi also asks for HTTPS on every micro frontend and a Content Security Policy, which means each team has to own part of the security posture of a page it does not fully control.

So the honest comparison is not code volume. It is whether you want one shared contract enforced by tooling, or several local ones maintained by hand.

## Licensing, compliance tooling and where to ask

Luigi is released under the Apache-2.0 licence, and the repository takes its third-party components seriously. Detailed information including third-party components and their licensing and copyright information is available through the REUSE tool, and the top level of the repository carries a LICENSES/ directory and a REUSE.toml file alongside the LICENSE. A REUSE status badge sits at the top of the README. For a project that ships to enterprise customers, that metadata trail matters, because the question of what is in the bundle and under which licence can be answered rather than guessed.

Support channels are documented. The README points to the GitHub Discussions page for questions, the Slack channel for contact, and GitHub issues for specific problems, asking that an issue describe the problem and the steps to reproduce it. Contributions go through the CONTRIBUTING.md file, and the repository has a CODE_OF_CONDUCT.md and a CODEOWNERS file.

The project also carries an OpenSSF Scorecard badge, which reflects the repository's own security posture tooling rather than a claim about the framework itself, but it does tell you that the maintainers track that kind of signal.

## Conclusion

Luigi suits teams that already run an administrative interface and need to split it into independently owned pieces, because it supplies the parts that are painful to rebuild: shared routing, navigation and authorization, plus a compatibility test that runs your application against older versions. It is the wrong tool for a consumer-facing product with no admin surface, and for teams unwilling to accept iframes as the isolation boundary. Verify first that your micro frontends satisfy the README guidelines, HTTPS only, a Content Security Policy, a restrictive Access-Control-Allow-Origin and an origin allowlist, because a micro frontend that skips them can talk to the core in ways you did not intend.

## FAQ

### What is Luigi and what problem does it solve?

Luigi is a micro frontend JavaScript framework for administrative user interfaces. It lets an application communicate with the micro frontends it contains, with routing, navigation, authorization and user experience settings configured centrally.

### How do Luigi Core and Luigi Client communicate?

They establish secure communication between the core application and the micro frontend using the postMessage API. The core passes the origin when you call the init listener in your micro frontend, which the client checks against its own allowlist of trusted domains.

### What security requirements does Luigi place on micro frontends?

The development guidelines say to make the micro frontend accessible only through HTTPS, add Content Security Policies, make the Access-Control-Allow-Origin header as restrictive as possible, and maintain an allowlist of trusted domains compared against the origin passed at init, stopping further processing if it does not match. Luigi also follows sandbox rules for iframes.

### How do I check that an application still works after upgrading Luigi?

Run the backward compatibility tests. Bundle Luigi with npm run bundle in the main repository folder, then run npm run test:compatibility in the same folder, adding --tag latest to preselect the last version. The script needs jq, which you can omit for a latest-tagged run.

### Does Luigi have any operating system or installation requirements?

The README states that Luigi can run on any operating system and that there are no specific requirements for installing it. Installation of the core and of the client are covered in separate documents on the documentation site, and the Luigi Fiddle is available to configure a sample application in the browser.

## Sources

- [License: Apache-2.0](https://github.com/luigi-project/luigi/blob/main/LICENSE)
- [luigi-project/luigi on GitHub](https://github.com/luigi-project/luigi)
- [Project website](https://luigi-project.io)
- [README](https://github.com/luigi-project/luigi/blob/main/README.md)
- [Releases](https://github.com/luigi-project/luigi/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/luigi-project-luigi
