This is the third part in a tenuously linked series defending JavaScript singletons in a modern world. I've previously written about extending EventTarget to allow for a fully typed, native event bus and how to connect a singleton to React without having to worry about the UI going out of sync or unwanted re-render calls.
Today I'll be looking at how we can use singletons alongside Micro-Frontends (MFEs) in order to allow information and state to be passed around even if you're using different frameworks.
Framework Independence
In a modern and fast-paced work environment, you might find several different teams all working on the same project. While we might hope that everyone across all of those teams uses the same framework to make our lives easier, that is not always possible or cost-effective. Fortunately, that is where micro-frontends come in. They allow a single wrapper in one framework to contain children from another. It is quite common to see the app bar written in one framework to provide global navigation, while the content is written in whatever way the team working on it deems fit.
Because of this, we can often end up in a mess where the same feature is implemented several times across each MFE, simply because communication between different frontends and frameworks is hard. By moving our logic outside of this and calling the same singleton from each MFE, we suddenly have easy communication, and the experience for the end-user feels a lot more unified and succinct.
Implementing Framework Adapters
In my last post, I demonstrated how to create a ToastManager singleton and have it seamlessly connect with React. We are going to use the exact same singleton today, but connect it to a few more things.
I'm going to be using single-spa for this demo because it is straightforward and offers plenty of examples to work from. This is not a tutorial on single-spa specifically, so I may skip over some of the initial setup.
Adding the Singleton
To add the singleton, I created a directory at the top level called libs/shared-utility/src. This contains the exact code from my last post; no changes were required as the singleton is designed to be framework-agnostic.
To make consumption easier across the project, I set up a path alias so the singleton can be imported consistently. In the vite.config.ts, I added a resolve key to defineConfig:
resolve: {
alias: {
"@org/toast-service": resolve(
__dirname,
"libs/shared-utility/src/toast-service.ts"
)
}
},
I then mirrored this in the tsconfig.json by adding a custom path:
"paths": {
"@org/toast-service": ["./libs/shared-utility/src/toast-service.ts"]
}
With these in place, I can now import the singleton from anywhere in the monorepo using a clean, consistent import:
import { toastManager } from "@org/toast-service";
single-spa provides various adapters to support your framework of choice, and since our singleton is now accessible from any of them, we simply need to implement the consumers. I will not be doing a deep dive into the specific build process for each application in this post, but the full implementation details are available in the source code.
In my demonstration, I used React to handle the primary toast display logic, while a variety of other frameworks, all supported by single-spa, are used to trigger the toasts. This illustrates the benefits beautifully the emitting framework does not need to know anything about the receiving framework, as they both communicate solely through the shared singleton.
Live Demonstration
That is more than enough waffle from me; let us have a look at the demo.
Link2Twenty
/
multi-framework-singleton-demo
Render several MFEs to demonstrate shared singletons
Cross-Framework Singleton Micro Frontends
This is a sample project demonstrating how singletons can be successfully implemented and accessed by different frameworks when using a Micro Frontend (MFE) architecture.
The build is accessible here.
Overview
In a Micro Frontend application, sharing state or utilities across different standalone applications can be challenging. This project shows how a singleton (in this case, a shared Toast Service) can be instantiated once and utilized seamlessly across multiple MFEs built with different web frameworks.
Currently includes standalone triggers for:
- React
- Vue
- SolidJS
- Svelte
- Preact
- Vanilla JS
Inspiration and Context
This project draws inspiration from the concepts discussed in the article: React singletons aren't as evil as you think.
While singletons are sometimes considered an anti-pattern in standard monoliths, they offer a very practical and effective way to manage shared global state (like a toast bus, authentication state, or theme configurations) across disjointed micro frontends…
Each element with a dotted border is a separate injected frontend. It is not common to have so many different frameworks on a single page, but for the sake of the demo, the more the merrier.
Click on the image or here to try the demo. Every button you see is part of a different framework application (React, Vue, Svelte, Preact, etc.), but they are all communicating with a single shared instance of our ToastManager.
Wrapping up
There we have it. We have the ability to allow multiple different micro-frontends to talk to each other as if they were all the same frontend. I think, if used correctly, this shows how powerful, lightweight and even type-safe the native web can be. Let me know if you have got anything like this in production or even if you have any reservations on this technique.
Thanks for reading! If you'd like to connect, here are my BlueSky and LinkedIn profiles. Come say hi 😊

Top comments (1)
This was the first use case I could think of to make a demo with but I'm sure there are so many other ways this could be useful. From sharing auth status to tracking user settings. I'd be really interested in hearing anyways in which you're using a singleton in an MFE or any other ideas you might have.