@island-chain/dom-bridge
v0.1.0
Published
**English** | [简体中文](README.zh-CN.md)
Readme
IslandChain
English | 简体中文
Documentation · 中文文档 · Documentation source · MIT License
The documentation site is hosted on GitHub Pages and updates automatically after pushes to main.
Current version: 0.1.0. The npm workflow publishes @island-chain/* when a matching GitHub Release is published. Manual runs default to dry-run; leave the tag empty to validate a branch. Configure the npm environment with NPM_TOKEN or trusted publishing before publication. Release setup.
A micro-frontend runtime for modern browsers. Each micro-application instance executes JavaScript in its own hidden, same-origin iframe Realm and renders visible DOM and CSS into an application-owned ShadowRoot.
The isolation model prevents accidental global pollution between trusted internal applications. A same-origin iframe is not a security boundary against malicious code.
Core model
Host Runtime
├─ AppController (state, cancellation, timeouts, resource cleanup)
├─ hidden iframe (per-instance window/globalThis/module graph)
└─ micro-app-host
└─ ShadowRoot
├─ micro-app-head
├─ micro-app-body ← props.container / document.body
└─ micro-app-overlay- Applications use
window,document, andglobalThisdirectly, without receiving synthetic globals through props. - JavaScript modules load through native
import()inside the iframe. The host does not use a global Proxy sandbox. - Visual operations on the iframe
documentare directed to the host ShadowRoot. Application CSS selectors cannot cross that boundary. props.containeris a real element created by the host Document. ItsownerDocumentand constructor identity retain host semantics; the DOM Bridge provides dual-Realminstanceofcompatibility for common Web IDL constructors.- Native and compatibility APIs share the same Runtime Core, AppController, and isolation model.
- An optional cross-origin isolation mode keeps both UI and JavaScript inside a visible sandboxed iframe and exchanges structured lifecycle messages through MessageChannel.
- An optional SSR protocol streams Declarative Shadow DOM. The client reuses existing nodes and hydrates through the original iframe Realm.
- The server registry can generate CSP-safe application bootstrap code and a dynamic host Import Map. The client registers applications with the same Runtime.
Development
Requires Bun 1.4, Node.js 20.19+ for the Vite toolchain, and a modern browser.
bun install --frozen-lockfile
bun run devFixed ports: host 5173, Vanilla 5174, React 5175, Vue 3 5176, compatibility example 5177, documentation 5178, Vue 2 5179, and component matrix 5180.
Run bun run verify for the combined validation gates, including the core checks below, mobile emulation, artifact size checks, and tarball template acceptance tests.
See release readiness and external acceptance for release boundaries. Core checks can also run individually:
bun run .agents/skills/micro-framework-engineering/scripts/check-architecture.ts
bun run typecheck
bun run build
bun run test:unit
bun run test:browser
bun run test:e2e
bun run test:production
bun run benchmarkNative Runtime API
import { createRuntime } from "@island-chain/runtime";
const runtime = createRuntime({
concurrency: "multiple",
timeouts: { load: 15_000, lifecycle: 15_000 },
});
runtime.registerApps([
{
name: "orders",
entry: { url: "https://apps.example.com/orders/entry.js", type: "module" },
container: "#orders-slot",
activeWhen: "/orders",
props: { tenantId: "north" },
},
]);
await runtime.start();Use the same Runtime without routing:
const handle = await runtime.mountApp({
name: "orders-panel",
entry: "https://apps.example.com/orders/entry.js",
container: panel,
props: { orderId: "A-1024" },
});
await handle.update({ orderId: "A-2048" });
await handle.unmount();
await handle.dispose();Optional document.write compatibility
The default Runtime excludes parse5 and the streaming writer. When an application actually calls document.write / writeln or ordinary
document.open / close, the framework blocks the call and logs deduplicated installation and configuration guidance.
To enable compatibility, explicitly configure the optional package, using the same version as the Runtime, before loading applications:
import { createRuntime } from "@island-chain/runtime";
import { installDocumentWrite } from "@island-chain/document-write";
const runtime = createRuntime({
documentBridge: { documentWrite: installDocumentWrite },
});Detection happens when a method is called. The framework neither scans source code nor downloads the optional package automatically.
See document.write compatibility for installation steps and compatibility boundaries.
Application entries
A native ESM entry exports lifecycle functions directly:
import type { AppProps } from "@island-chain/runtime";
export function bootstrap(props: AppProps) {
window.applicationBootstrapped = true;
}
export function mount(props: AppProps<{ title: string }>) {
const root = document.createElement("main");
root.textContent = props.title;
document.body.append(root);
}
export function unmount() {
document.querySelector("main")?.remove();
}An HTML Entry can contain a template, styles, and an external ESM lifecycle entry. Relative template resources and CSS url() references resolve to absolute URLs using the entry URL as their base.
React, Vue 3, Vue 2, and Vanilla adapters are available in @island-chain/adapter-react, @island-chain/adapter-vue, @island-chain/adapter-vue2, and @island-chain/adapter-vanilla, respectively. Portal, Teleport, and append-to-body overlays use the bridged document.body to cover the host viewport by default, while their DOM and styles remain owned by the current ShadowRoot. When a developer supplies an explicit container, overlays position relative to that container. The example matrix covers Ant Design, Element Plus, Element UI, Quill, Monaco Editor, Apache ECharts, Leaflet, and MapLibre GL.
Compatibility API
The main package also exports familiar registration and control functions:
import { registerMicroApps, start } from "@island-chain/runtime";
registerMicroApps([
{
name: "orders",
entry: "https://apps.example.com/orders/",
container: "#orders-slot",
activeRule: "/orders",
},
], {
afterMount: [(app) => console.log(app.name)],
});
await start({ prefetch: true, singular: false });Compatibility covers calling conventions and key observable behavior. Realm isolation, Shadow DOM, and the state machine retain the current implementation. See compatibility and migration.
Migration and project CLI
The main reason to migrate from qiankun is to make real per-instance Realms, consistent Shadow DOM, host resource ownership, and cleanup that completes even after failures part of one Runtime contract. Changing APIs or improving a single benchmark alone does not justify migration. If an existing system runs reliably and has no clear isolation or governance problems, switching frameworks may not be worthwhile. See migrating from qiankun for decision criteria and optimization evidence.
@island-chain/migration-tools converts qiankun/wujie configuration and uses the TypeScript AST to scan for host escape paths, legacy global protocols, Web Storage, dynamic code, Service Workers, and other migration risks. The codemod rewrites only qiankun named imports with established compatibility; it does not execute the source being migrated.
micro-frame scan-source src --json
micro-frame scan-source src --write
micro-frame diagnose --config micro-frame.deploy.json
micro-frame create apps/orders --framework react
micro-frame dev --config micro-frame.dev.jsonUpstream issue regression ledger
The local regression ledger records qiankun/wujie sources, actual bug labels, per-issue verification progress, and local test results. Check the ledger before collecting more reports. Imports are deduplicated by repository and issue number; later collections do not overwrite processed records.
bun scripts/upstream-issues.mjs list
bun scripts/upstream-issues.mjs checkVerification evidence and limitations
- Vitest: 192/192 contract, unit, and Node integration tests across 55 files passed in the September 14, 2026 optimization acceptance run.
- Vitest Browser Mode: 507/507 passed across Chromium, Firefox, and WebKit after extracting the optional writer. Before application navigation, each context verified zero outbound Sentry delivery across five transport types using a local receiver and blocked Service Workers.
- Real macOS Safari (historical evidence, not rerun during the optimization work): the September 8, 2026 unlocked-device verification passed all 48 package contracts then present, plus 3/3 application Tooltip/Menu scenarios for React/Ant Design, Vue 3/Element Plus, and Vue 2/Element UI. SafariDriver requires the Mac to remain unlocked.
- Playwright: the full E2E run after extracting the optional writer passed 423 scenarios. After updating the old default-write assertion, the remaining three scenarios passed a targeted rerun across the three engines. On macOS, browsers run in separate processes per test file; all application contexts use the same outbound-telemetry protection.
- Playwright Mobile: two touch, viewport, and cleanup contracts passed 4/4 across emulated Android/Chromium and iPhone/WebKit devices. Emulation is not evidence from physical devices or real iOS Safari.
- Playwright Production: all 12 Hydration/SSR/CSP scenarios compatible with local protection passed. The offline-cache scenario requires Service Worker registration, which conflicts with the mandatory Service Worker block, so protection was not disabled to rerun it.
- CLI template pages passed 24/24, and Angular AOT/Vite/Webpack integration passed 6/6 under the same protection.
- Playwright Benchmark: 43 passed, with two non-Chromium precise heap measurements skipped by design. Repeated HTML Entry mount P95 improved by 27.7%/37.1%/25.8% in Chromium/Firefox/WebKit against the frozen baseline. Heap growth in three real component sessions was approximately 0.20–0.23 MiB; Document, host, iframe, and application resource counts remained stable or returned to zero.
- Historical
benchmark:soakevidence (September 2, 2026, not rerun during the optimization work): 12/12 passed after 60 continuous minutes in each of Chromium, Firefox, and WebKit. At a 1 Hz cadence, 10,784 independent instances completed in total, with zero remaining DOM/iframe instances and no mount/dispose operations exceeding one second in any engine. - DevTools includes an inspector for multiple instances sharing a name, a network waterfall, optional telemetry, and a local Chromium extension. The extension passed actual loading and panel interaction tests.
- Loading cancellation/timeouts, Realm asynchronous error forwarding, and server-side user/tenant rollout are implemented. See Angular/Webpack integration for its supported scope.
- Historical Safari Vitest/WebdriverIO gates passed 48/48 package contracts and 3/3 application scenarios. Real-browser testing uncovered and led to fixes for a Channel subscription readiness race, the DevTools network-clear watermark, and prefetch fallback when IntersectionObserver missed visibility changes caused by
style/class/hidden. - Verified behavior includes global variable, prototype, module instance, DOM query, and CSS isolation; React Portal and Vue Teleport; React/Vue 3/Vue 2 component-library Tooltip/Menu behavior; dual instances; rapid route cancellation; and destruction cleanup.
- Playwright WebKit is not real Safari. The repository keeps separate three-engine headless and macOS SafariDriver gates. iOS Safari and physical mobile devices still require external verification.
- The complete default Runtime production consumer artifact is
49,971 B gzip, passing the50,000 Bgate with all 13 public exports and the full module graph. Baseline7aa531emeasured60,386 Busing the former ES-library format and54,122 Bwith equivalent complete production minification; source improvements should be compared with the latter. Runtime Core is9,145 B, bootstrap304 B, and the separate optionaldocument-writepackage53,243 B. Measurement sums gzip across every JS chunk and includes actual sourcemap URLs. See release acceptance.
See implementation status for the full status and browser support for capabilities and hard limits. The overall plan is maintained in RODEMAP.md.
Documentation site
The September 7, 2026 additions include independent previews and tarball consumer acceptance for four CLI frameworks (24/24), React/Vue 3 Hydration, CI configuration, private tarball preparation, artifact integrity checks, and size budgets. Documentation has been built and deployed through GitHub Actions, and the current Runtime size gate passes. Confirm publication through registry version and integrity checks; see the release documentation above for physical-device and external production acceptance requirements.
The documentation site lives in packages/docs and builds Chinese and English editions with VitePress.
bun run docs:dev
bun run docs:build
bun run docs:build:site
bun run docs:previewdocs:build:site includes the host and all four micro-applications in /playground/, embedded in the documentation demo page.
Set DOCS_BASE=/micro-framework/ for GitHub Pages project paths; the deployment workflow also runs the three-browser demo checks before publishing.
