qiankun and single-spa are both JavaScript libraries designed to enable micro-frontend architectures, allowing teams to build applications composed of multiple independent fragments that can be developed, deployed, and scaled separately. single-spa is the foundational framework that provides the core routing and lifecycle management for stitching together different frameworks (React, Vue, Angular, etc.) in a single page. qiankun is built on top of single-spa and extends it with additional features focused on isolation, such as JavaScript sandboxing and CSS scoping, aiming to provide a more complete out-of-the-box solution for enterprise-grade micro-frontends.
Both qiankun and single-spa solve the same fundamental problem: how to run multiple frontend applications within a single browser tab without them breaking each other. However, they approach this challenge with different levels of abstraction and built-in safeguards. Let's compare how they handle registration, isolation, and communication.
single-spa requires you to manually define activity functions that determine when an app should be active. You register each application individually with a name, a loading function, and a condition.
// single-spa: Manual registration with activity function
import { registerApplication, start } from 'single-spa';
registerApplication({
name: '@myorg/app-one',
app: () => System.import('@myorg/app-one'),
activeWhen: (location) => location.pathname.startsWith('/app-one'),
customProps: { store: myStore }
});
start();
qiankun simplifies this by grouping registrations into a single configuration array passed to registerMicroApps. It handles the routing logic internally based on the activeRule.
// qiankun: Batch registration with activeRule
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'app-one',
entry: '//localhost:7100',
container: '#container',
activeRule: '/app-one',
props: { store: myStore }
}
]);
start();
single-spa does not provide JavaScript sandboxing out of the box. If two apps modify the same global variable (like window.user), they will conflict. You must rely on build tools (like Webpack Module Federation) or strict coding conventions to avoid this.
// single-spa: No built-in sandbox
// Risk: App A and App B both access window.globalConfig
window.globalConfig = { theme: 'dark' }; // App A
window.globalConfig = { theme: 'light' }; // App B overwrites it
qiankun includes a JavaScript sandbox that runs micro-apps in a Proxy-based environment. This prevents child apps from polluting the global window object, ensuring that global variables stay local to the app.
// qiankun: Proxy Sandbox enabled by default
// App A modifies window within its sandbox
window.localConfig = { theme: 'dark' };
// App B cannot see window.localConfig from App A
// When App A unmounts, the sandbox cleans up global side effects
single-spa relies on CSS naming conventions (like BEM) or CSS Modules to prevent style conflicts. It does not automatically scope styles, so a global CSS reset in one app can break another.
/* single-spa: Manual scoping required */
.app-one-button { background: blue; } /* Must use unique prefixes */
.app-two-button { background: red; }
qiankun offers built-in CSS scoping. It can rewrite styles to ensure they only apply within the micro-app's container. It also supports Shadow DOM for stricter isolation, though this comes with its own trade-offs regarding event bubbling.
/* qiankun: Automatic scoping via data attributes */
/* qiankun adds data-qiankun-app-one to the container */
[data-qiankun-app-one] .button { background: blue; }
/* Styles are scoped automatically during runtime */
single-spa expects each micro-app to export specific lifecycle functions (bootstrap, mount, unmount). The framework calls these at the right times, but you must implement them in every sub-application.
// single-spa: Explicit lifecycle exports in sub-app
export async function bootstrap(props) { /* init */ }
export async function mount(props) { /* render */ }
export async function unmount(props) { /* cleanup */ }
qiankun also uses these lifecycle hooks but wraps them to handle the sandboxing and container mounting automatically. If you are using a supported framework (like Vue or React), qiankun provides helpers to reduce boilerplate.
// qiankun: Lifecycle with sandbox context
export async function render(props) {
const { container } = props;
// Render logic here, qiankun handles the container injection
ReactDOM.render(<App />, container.querySelector('#root'));
}
export async function mount(props) { render(props); }
export async function unmount(props) { /* cleanup */ }
single-spa does not enforce a specific way to share state between apps. Developers typically use custom events, a shared store module, or browser storage (localStorage).
// single-spa: Custom event bus pattern
window.dispatchEvent(new CustomEvent('USER_LOGIN', { detail: user }));
// Another app listens for this event
qiankun provides a built-in global state API called initGlobalState. This allows the main app and micro-apps to share reactive data without setting up external libraries.
// qiankun: Built-in global state
import { initGlobalState } from 'qiankun';
const actions = initGlobalState({ user: null });
actions.onGlobalStateChange((state) => {
console.log('User updated:', state.user);
}, true);
These libraries are powerful but add complexity. Consider alternatives when:
| Feature | single-spa | qiankun |
|---|---|---|
| Core Basis | Vanilla JS Core | Built on top of single-spa |
| JS Isolation | β Manual (Build tools) | β Proxy Sandbox (Built-in) |
| CSS Isolation | β Manual (Naming conventions) | β Automatic Scoping / Shadow DOM |
| Registration | Individual registerApplication | Batch registerMicroApps |
| Global State | β Custom implementation | β
initGlobalState API |
| Setup Complexity | Medium (More config) | Low (More conventions) |
Think in terms of isolation needs and team structure:
qiankun. The built-in sandboxing saves time and prevents hard-to-debug global conflicts.single-spa. It gives you the raw tools to build your own architecture without hidden magic.qiankun is often easier for incremental adoption because it handles more edge cases automatically.Final Thought: Both tools enable the same architectural pattern, but qiankun acts as a batteries-included layer over single-spa. If you don't need the extra isolation features, single-spa keeps your dependency tree smaller. If you need enterprise-grade safeguards, qiankun is worth the trade-off.
Choose qiankun if you need stronger isolation guarantees between micro-apps without configuring complex build pipelines. It is ideal for teams that want built-in JavaScript sandboxing and CSS scoping to prevent global variable conflicts and style leaks. This package works well for organizations migrating from a monolith to micro-frontends where apps might be written by different teams using different versions of dependencies.
Choose single-spa if you prefer a lightweight core that gives you full control over how isolation and routing are implemented. It is suitable for teams that want to build custom tooling around their micro-frontends or need to support legacy systems with specific constraints. This approach is best when you want to avoid the opinionated structure of qiankun and manage lifecycle methods manually.
In Chinese,
qian(δΉΎ)means heaven andkun(ε€)earth.qiankunis the universe.
Qiankun enables you and your teams to build next-generation and enterprise-ready web applications leveraging Micro Frontends. It is inspired by and based on single-spa.
A quick recap about the concept of Micro Frontends:
Techniques, strategies and recipes for building a modern web app with multiple teams using different JavaScript frameworks. β Micro Frontends
Qiankun was birthed internally in our group during the time web app development by distributed teams had turned to complete chaos. We faced every problem micro frontend was conceived to solve, so naturally, it became part of our solution.
The path was never easy, we stepped on every challenge there could possibly be. Just to name a few:
After solving these common problems of micro frontends and lots of polishing and testing, we extracted the minimal viable framework of our solution, and named it qiankun, as it can contain and serve anything. Not long after, it became the cornerstone of hundreds of our web applications in production, and we decided to open-source it to save you the suffering.
TLDR: Qiankun is probably the most complete micro-frontend solution you ever metπ§.
Qiankun inherits many benefits from single-spa:
And on top of these, it offers:
$ yarn add qiankun # or npm i qiankun
You can find the Qiankun documentation on the website
Check out the Getting Started page for a quick overview.
The documentation is divided into several sections:
Inside the examples folder, there is a sample Shell app and multiple mounted Micro FE apps. To get it running, first clone qiankun:
$ git clone https://github.com/umijs/qiankun.git
$ cd qiankun
Now install and run the example:
$ yarn install
$ yarn examples:install
$ yarn examples:start
Visit http://localhost:7099.

Thanks to all the contributors!
Qiankun is MIT licensed.