# QIANKUN PROJECT KNOWLEDGE BASE **Updated:** 2026-07-06 · **Commit:** dcc42ae4 · **Branch:** next (qiankun 3.0, active dev) Qiankun is a micro-frontend framework built on [single-spa](https://github.com/single-spa/single-spa). v3 rewrites the runtime around **streaming HTML-entry loading**, a **Proxy-membrane JS sandbox**, and native **ESM-sandbox** execution. It is a pnpm monorepo built with Vite 8; `tsc` emits package declarations. > Requires Node `^22.15 || >=24`, `pnpm@11.13.1` (see `packageManager`). Never use npm/yarn at the root. ## STRUCTURE ``` qiankun/ ├── packages/ │ ├── qiankun/ # Facade: public APIs (register/loadMicroApp, start, prefetch) + loadApp orchestration │ ├── sandbox/ # JS isolation: Proxy membrane + Compartment → packages/sandbox/AGENTS.md │ ├── loader/ # Streaming HTML-entry loader (writable-dom) → packages/loader/AGENTS.md │ ├── shared/ # Transpilers, fetch-utils, module-resolver, ESM-sandbox engine → packages/shared/AGENTS.md │ ├── single-spa/ # Vendored single-spa fork (@qiankunjs/single-spa, upstream 7.0 @ ce0f925a) → packages/single-spa/README.md │ ├── ui-bindings/ # components: react/ vue/ shared/ (dogfooded by examples/{main,vue-host}) │ └── bundler-plugin/ # Webpack(4/5) + Vite plugins: mark entry script, fix output library ├── skills/ # Agent skills (installed by users via `npx skills add umijs/qiankun`) — content, not code: no build/publish ├── e2e/ # Playwright, runs against BUILT dist → e2e/README.md ├── examples/ # Runnable demos: two hosts (main = @qiankunjs/react, vue-host = @qiankunjs/vue) + react/vue/purehtml/webpack └── docs/ # VitePress site (docs/rfcs holds design RFCs) ``` ## PROGRESSIVE DISCLOSURE — read the scoped doc before editing a package | Working in… | Read first | | --- | --- | | `packages/sandbox/**` | [`packages/sandbox/AGENTS.md`](packages/sandbox/AGENTS.md) — membrane, compartment, patchers, ESM globals | | `packages/loader/**` | [`packages/loader/AGENTS.md`](packages/loader/AGENTS.md) — streaming pipeline, head virtualization | | `packages/shared/**` | [`packages/shared/AGENTS.md`](packages/shared/AGENTS.md) — transpilers, fetch decorators, **esm-sandbox** | | `e2e/**` | [`e2e/README.md`](e2e/README.md) — Playwright layout, fixtures, anti-flake rules | ## ARCHITECTURE (big picture) `loadApp` (`packages/qiankun/src/core/loadApp.ts`) is the orchestrator. Per micro-app it wires: 1. **fetch** — decorated `window.fetch`: `makeFetchCacheable(makeFetchRetryable(makeFetchThrowable(fetch)))`. 2. **sandbox** — `createSandbox()` builds a Proxy-membrane `window`/`document` view; patchers (dynamicAppend, timers, listeners, history) each return a `free()` cleanup called on unmount. Without a container it uses the JS-only preset; a container enables DOM containment. 3. **loader** — `loadEntry(entry, container, opts)` streams the HTML entry through `writable-dom`, virtualizing `` → `` and running each node through a `nodeTransformer`. 4. **transpilers** (`shared/assets-transpilers`) rewrite each script/link/style node before it hits live DOM. Micro apps sharing one container element take FIFO turns for their DOM writes through the **container occupancy gate** (`core/containerOccupancy.ts`, two critical sections: load-phase streaming and mount→unmount; see `docs/rfcs/container-occupancy-gate.md`). Two execution paths, chosen per script type: - **Classic** (`