Skip to content
Agentmart
Submit a tool

AGENTS.md · umijs/qiankun

AGENTS.md from umijs/qiankun: 135 lines covering STRUCTURE, PROGRESSIVE DISCLOSURE — read the scoped doc before editing a package, ARCHITECTURE (big picture)…

Template by umijs

IndexedMIT★ 16,697
Write a review

Chalk Labs

Need help deploying AGENTS.md · umijs/qiankun?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.

curl -fsSL https://raw.githubusercontent.com/umijs/qiankun/next/AGENTS.md -o AGENTS.md

Read it and adapt it to your project before use.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

The AGENTS.md file that umijs/qiankun (16,697 stars) keeps for coding agents. It has 135 lines in 8 sections: STRUCTURE; PROGRESSIVE DISCLOSURE — read the scoped doc before editing a package; ARCHITECTURE (big picture); COMMANDS; CONVENTIONS (enforced by ESLint flat config — pnpm run eslint will reject violations); DOCS & README CONVENTIONS; ANTI-PATTERNS (this project); NOTES. Use it as a model for your own project's instructions.

Use cases: prompt-engineering

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

What's in it

An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.

For
Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
Length
135 lines
File
AGENTS.md

Sections

  1. STRUCTURE
  2. PROGRESSIVE DISCLOSURE — read the scoped doc before editing a package
  3. ARCHITECTURE (big picture)
  4. COMMANDS
  5. CONVENTIONS (enforced by ESLint flat config — pnpm run eslint will reject violations)
  6. DOCS & README CONVENTIONS
  7. ANTI-PATTERNS (this project)
  8. NOTES

First lines (shown under the repo's MIT license)

# 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/     # <MicroApp> 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 `<head>` → `<qiankun-head>` 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** (`<script entry>`, UMD/global): source is wrapped and run via a **blob URL** scoped to the sandbox membrane. The app's export = `sandbox.latestSetProp` (the last global the entry script set).
- **ESM** (`<script type="module">`): handled by `EsmSandboxEngine` (`shared/esm-sandbox`). Modules are fetched, lexer-rewritten to route globals through the membrane, given synthetic specifiers via a dynamically injected **import map**, and evaluated in order. The engine also handles dynamic `import()`.

**Style isolation** (`shared/assets-transpilers/style.ts` + `link.ts`) uses CSS `@scope` at runtime; external stylesheets become blob-`<link>`s so `@scope` can wrap them. Opt-in via `styleIsolation`.

Internal dependency graph (never invert it):

```
qiankun → loader → sandbox → shared
                   sandbox → shared
qiankun → single-spa   (vendored fork; zero deps, bottom of the graph — must not import shared/sandbox/loader)
ui-bindings/{react,vue} → ui-bindings/shared → qiankun
```

## COMMANDS

```bash
pnpm install                 # install all workspace deps

# build (Vite 8 → package JavaScript; tsc → declarations)
pnpm run build               # build everything (packages + examples)
pnpm run build:packages      # build only packages/** (prereq for e2e & examples)

# unit tests — vitest + happy-dom, aliased to src (NO build needed, see vitest.config.ts)
pnpm run test                            # all packages
pnpm --filter @qiankunjs/shared run test # one package
pnpm --filter @qiankunjs/sandbox exec vitest run path/to.test.ts   # single file
pnpm --filter @qiankunjs/shared  exec vitest run -t "test name"    # single test by name

# e2e — Playwright against BUILT dist (see e2e/README.md)
pnpm run test:e2e            # build all + run chromium suite

# lint / format / full CI gate
pnpm run eslint              # eslint packages/
pnpm run prettier:check      # prettier -c .
pnpm run ci                  # build + eslint + prettier:check (what CI runs)

# dev
pnpm run start:example       # build packages + run all example apps in parallel
pnpm run docs:dev            # VitePress docs
```

## CONVENTIONS (enforced by ESLint flat config — `pnpm run eslint` will reject violations)

TypeScript is strict + type-checked (`typescript-eslint`'s type-checked flat config):

- **No `any`** — `no-explicit-any` auto-fixes to `unknown`. No `as any`, `@ts-ignore`, `@ts-expect-error`.
- **Inline type imports** — `import { type Foo, bar }`, not `import type { Foo }` on its own line (`consistent-type-imports`/`consistent-type-exports` with `fixStyle: inline-type-imports`).
- `no-unnecessary-condition` is an error — don't guard values the types prove are always truthy.
- Unused vars/args must be prefixed `_` (`argsIgnorePattern: ^_`).
- `array-simple`: `T[]` for simple, `Array<T>` for complex element types.
- JS-wide: `no-else-return` (no `else` after `return`), `object-shorthand`.
- Path alias `@qiankunjs/*` → `packages/*/src` (tsconfig + vitest); imports resolve to **source**, not dist.

Build/release:

- Vite 8 builds browser package JavaScript as ESM+CJS, while `tsc` emits declarations. Package entry fields and subpath exports must point at the corresponding `dist` outputs.
- TypeScript 7 is installed as `@typescript/native` and owns the `tsc` binary. The `typescript` dependency intentionally aliases `@typescript/typescript6` because TypeScript 7.0 has no programmatic API yet and tools such as `typescript-eslint` and `vue-tsc` still require that compatibility API.
- Versioning via **changesets**, but changesets are **auto-derived from Conventional Commits** in CI (`scripts/generate-changesets.mjs`) — do **not** hand-write `.changeset/*.md`. Just land a well-formed conventional commit (`feat`/`fix`/`feat!`…); the release job maps changed files → packages and infers the bump. Each sub-package keeps its own `CHANGELOG.md` (changeset default, visible on npm); on publish `scripts/generate-release-notes.mjs` aggregates them into **one GitHub Release**, which can be polished after the fact via the `/release-changelog` skill (`gh release edit`). Full flow: `.changeset/README.md`.
- Conventional commits enforced by commitlint (`feat:`, `fix:`, `feat(esm-sandbox):`, …).

## DOCS & README CONVENTIONS

- **Chinese-first.** The primary audience is Chinese. `docs/zh-CN/` is the source of truth: write it to a native-author standard — no translationese, no AI-flavored filler (「让我们」「值得注意的是」「强大的/无缝的」), no calqued English syntax. The English pages align to the Chinese semantics, not the other way around; pure zh wording fixes don't require touching en. Same contract for `README.zh-CN.md` ↔ `README.md`: keep both editions in sync whenever either changes.
- **Mainland reachability is a hard constraint.** Google Fonts only via the `.cn` mirrors (`fonts.googleapis.cn`/`fonts.gstatic.cn`); never reference resources on domains unreachable from mainland China.
- **Domains**: canonical docs domain is `https://www.qiankunjs.com` (zh under `/zh-CN/`); `qiankun.umijs.org` stays alive and 307s to it; v2 docs live at `v2.qiankun.umijs.org`; live examples at `examples.qiankunjs.com`. Old-site URLs are kept working via `docs/public/_redirects` — extend it when moving pages, never break inbound links.
- **Consistency rules**: terminology never drifts (主应用/微应用/沙箱/隔离膜; qiankun always lowercase); link text in reference lists ("相关内容"/"继续阅读"/"延伸阅读") equals the target page's H1; API pages use 「函数签名」/「默认值为 X」; `guide/browser-support` is the single source of truth for browser requirements — link it, don't restate version numbers elsewhere.
- Until 3.0 reaches npm `latest`, install commands must say `qiankun@rc`, and the site shows a version banner (layout-top slot in `docs/.vitepress/theme/index.js`; remove it together with `--vp-layout-top-height` once stable ships).
- **README GitHub alerts**: put the `[!WARNING]`/`[!NOTE]` marker on its own line followed by a blank `>` line. Prettier's `proseWrap: never` re-joins plain soft breaks, which silently breaks alert rendering.
- VitePress compiles every `.md` as a Vue SFC: bare `<Tag>` in prose/link text or `{{` in inline code breaks the build (fenced code blocks are safe).

## ANTI-PATTERNS (this project)

- **NEVER** put more than one `entry` script in an HTML entry — the loader throws `QiankunError`.
- **ALWAYS** unmount micro-apps; `loadMicroApp`/patchers return handles/`free()` — leaks break remount & multi-instance.
- In sandbox code, **never touch the real `window`/`document.head`** — go through the proxied view.
- The vendored `loader/src/writable-dom/` fork accepts **generic designs only** — never qiankun-coupled semantics; caller bookkeeping goes through its `assetTransformer` callback (see `packages/loader/AGENTS.md`).
- Don't invert the package dependency graph above (e.g. `shared` must not import `sandbox`).
- e2e: never `waitForTimeout`; use web-first assertions; all ports come from `e2e/ports.ts`.
- Performance work is judged in this order: **proportional impact first** (does the win scale with asset size / network / app scale — e.g. eliminating a duplicate download), **readability second** (never trade it away for small wins), **constant absolute savings last** (fixed single-digit-ms pipeline costs are noise in real apps and rarely worth landing). Beware: the ~50ms benchmark fixture makes fixed milliseconds masquerade as percentages — convert to absolute ms against realistic load times before deciding. And fix root causes at the source, not with per-call-site markers/exemptions downstream.

## NOTES

- Firefox doesn't support dynamically injected import maps → ESM-sandbox e2e tests are annotated `test.fail(firefox, …)` (expected failure, not skip). See `e2e/README.md`.
- Design decisions live in `docs/rfcs/` (e.g. the ESM-sandbox RFC).
- v3 roadmap: github.com/umijs/qiankun/discussions/1378.

Signals

Stars
16,697
Forks
2,059
Open issues
402
Last commit (this folder)
Aug 11, 2026 (2 months ago)
Last release
Nov 15, 2023 (2 years ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get AGENTS.md · umijs/qiankun running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying AGENTS.md · umijs/qiankun?

CallGet help
Cite this page

AGENTS.md · umijs/qiankun. Agent Mart. https://agentmart.dev/templates/umijs-qiankun-agents-md (last updated 2026-10-24)