npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wu-framework

v3.2.1

Published

Universal Microfrontends Framework - 13 frameworks, zero config, Shadow DOM isolation

Readme

WU Framework

Compose independently built web applications in one shell. WU loads their entries, coordinates mounting, updates and cleanup, and connects them through shared state, events and versioned services. Each application keeps its rendering framework and build toolchain.

Documentation · npm · WU CLI · Examples · Support

Documentation is available in English, Simplified Chinese, Portuguese and Spanish. This README describes 3.2.1; the changelog records release changes.

New in 3.2.0

| Capability | What to use | | --- | --- | | Explicit core composition | Optional subsystem imports and three manifest sources | | Installable applications | Signed .wuapp packages, trust, cache, restore and uninstallation | | Remote applications | Cross-origin iframes and revocable capability ports | | Candidate comparison | Shadow deployment and scoped operation interception | | Visual coordination | Transitions, focus, keep-alive and detachable windows | | Data transfer | Typed drag and drop with grants and keyboard alternatives | | Contract evolution | Version translators for services, RPC and provided objects | | Server rendering | Progressive SSR, response nonces and Trusted Types |

Use WU CLI 1.0.1 for templates targeting this release. The CLI shares WU core between the shell and apps; import optional subsystems explicitly in the shell when using that path. Standard wu-framework imports outside the CLI retain lazy subsystem loading. File manifests remain supported; inline and module-declared manifests are optional.

The remote entry includes TypeScript declarations. Same-origin app composition, remote iframe isolation, and package signature verification provide different guarantees; follow the linked contract for each feature. See upgrade steps before changing an existing workspace.

What you can build

  • A product that combines React, Vue, Angular, Svelte or other applications on the same page.
  • A gradual migration in which one capability changes framework while the shell and other applications remain in place.
  • Dashboards, storefronts and internal tools whose applications exchange events, shared state or typed service requests.
  • An Astro or Next shell that composes independently built applications, with SSR and hydration where the chosen integration supports them.
  • Optional background computation through Worker services and compatible WASI guests.

WU provides application composition and lifecycle APIs. You still choose the UI frameworks, route ownership, build tools, backend and deployment host.

Direct composition and independent runtimes

mount(name, target) accepts a CSS selector or an actual HTMLElement, including elements inside another Shadow DOM. Recovery and unmount preserve that host. Each new WuCore() owns its default store, memory cache, timing entries and resource hints. Destroying it preserves peer runtimes and their inspector. Explicitly injected stores and caches remain caller-owned.

Register app lifecycles with runtime.define(...) on the appropriate instance. The global wu singleton addresses the shared host. On an independent runtime, await runtime.timelineReady() before recording changes. For persistent caching, explicitly configure a WuCache storage backend and namespace, and clear it when its owner releases it.

Independent cores also expose windowsReady(), detach(), attach(), isDetached() and windowOf(). Await windowsReady() during setup before enabling a popup or PiP button, then call detach() from its click handler. Window coordination belongs to that core; it does not require the global singleton. See the interactive workspace guide.

Install and start a project

npm install wu-framework

The package provides ESM, CommonJS, UMD and TypeScript declarations. The core has no runtime package dependencies. Renderer peers are optional: install the renderer dependencies that each application actually uses. The npm package declares Node >=20; application toolchains can require a newer version.

To generate an Astro shell with React and Vue applications:

npm install -g @wu-framework/cli
wu create portal --template react --shell astro
cd portal
wu add vue catalog --no-install
wu install
wu dev --no-open

The quick create command generates files without installing. wu install installs the project's declared dependencies. Native development uses one HTTP origin, normally http://127.0.0.1:3000; it can still use Node compiler helpers and shell builds.

For a production preview, stop the development server, then run:

wu build
wu serve 4100 --mode static

Use SPA mode instead when the shell owns client-side routes. See the CLI manual.

Supported frameworks and custom integrations

The package includes 13 adapter entry points:

| Framework | Import | | --- | --- | | React | wu-framework/adapters/react | | Vue | wu-framework/adapters/vue | | Angular | wu-framework/adapters/angular | | Svelte | wu-framework/adapters/svelte | | Preact | wu-framework/adapters/preact | | Solid | wu-framework/adapters/solid | | Lit | wu-framework/adapters/lit | | Vanilla JavaScript | wu-framework/adapters/vanilla | | Alpine | wu-framework/adapters/alpine | | Qwik | wu-framework/adapters/qwik | | Stencil | wu-framework/adapters/stencil | | HTMX | wu-framework/adapters/htmx | | Stimulus | wu-framework/adapters/stimulus |

This list is not a limit on composition. A custom integration can register its own mount, update and unmount lifecycle. Adapter options, rendering requirements and hydration support differ; consult the integration guide and adapter reference.

Astro and Next have separate shell integrations under wu-framework/integrations/astro and wu-framework/integrations/next.

Understand the three pieces

  1. The shell provides DOM slots, registers application URLs and grants access to shared resources.
  2. An application manifest identifies the published JavaScript entry and requests its capabilities.
  3. The application entry registers a lifecycle, directly or through a framework adapter.

The application name must match in all three places. The shell mounts the application after its slot exists.

Shell

Place a slot in the shell's HTML:

<div id="greeting-slot"></div>

Run this module in the browser:

import { wu } from 'wu-framework';

await wu.init({
  sandbox: 'module',
  apps: [{ name: 'greeting', url: '/apps/greeting' }],
});
await wu.mount('greeting', '#greeting-slot');

// To fully remove this application and await teardown:
// await wu.unmount('greeting', { force: true });

Manifest

Serve this as /apps/greeting/wu.json:

{
  "name": "greeting",
  "entry": "assets/greeting.js",
  "styleMode": "own-only",
  "wu": { "permissions": [] }
}

Application entry

Build this source as the manifest's assets/greeting.js:

import { wu } from 'wu-framework';

wu.define('greeting', {
  mount(container) {
    const paragraph = document.createElement('p');
    paragraph.textContent = 'Hello from a WU application';
    container.append(paragraph);
  },
  unmount(container) {
    container.replaceChildren();
  },
});

These are integration files, not a standalone build configuration. The CLI generates that configuration for supported templates. With an existing build setup, publish the manifest and compiled entry at the declared URLs and make every imported dependency browser-resolvable. WU does not transpile source JSX or TypeScript in the browser.

For a script-tag installation, the package also exposes a versioned UMD build:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/wu-framework.umd.js"></script>

Use window.wu from that build. It supplies the runtime; applications still need their own entries, manifests and renderer dependencies.

Application lifecycle and scoped access

wu.init({ apps, ...options }) initializes the host once. wu.mount, wu.update, wu.unmount, wu.hide and wu.show control applications. wu.app(name, config) creates a reusable application wrapper. wu.destroy() releases the runtime.

unmount normally releases a mount reference and can defer teardown; keepAlive preserves the mounted app in a hidden state. Use await wu.unmount(name, { force: true }) when full teardown must finish before proceeding.

An application's mount(container, context) receives context.wu, a scoped facade. Use this facade for application state, events and services. The imported singleton belongs to the trusted shell and has host authority. Keep listener cleanup functions and release external resources during unmount.

Capabilities use two declarations: the application requests a resource in its manifest and the shell grants access in its app configuration. For example:

{
  "name": "counter",
  "entry": "assets/counter.js",
  "wu": {
    "permissions": [
      { "capability": "store.read", "resource": "demo.count", "required": true }
    ]
  }
}

The corresponding shell app configuration includes:

const counterConfig = {
  name: 'counter',
  url: '/apps/counter',
  grants: [{ capability: 'store.read', resource: 'demo.count' }],
};

The shell can set wu.store.set('demo.count', 1). The mounted application reads it with context.wu.store.get('demo.count'). Effective access is the intersection of requests and grants; the facade is revoked when its app lease ends.

The six capability names are store.read, store.write, events.emit, events.subscribe, rpc.call and rpc.provide. Client capabilities do not replace server authentication or domain authorization. See security.

State, events and requests

Choose the primitive that matches the interaction:

| Need | API | Cleanup or constraint | | --- | --- | --- | | Read or change shared data | wu.store.get, set, update, batch | Reads are detached snapshots; notifications run in microtasks | | Observe a state path | wu.store.on(path, callback) | Keep the returned unsubscribe function | | Announce a fact | wu.emit, wu.on, wu.once, wu.off | Event callbacks receive an envelope; payload is event.data | | Request an async result | wu.request, wu.handle | Timeouts, AbortSignal, version ranges and caller allow lists | | Share an object interface | wu.provide, wu.consume | Versioned proxy; provider handle has revoke() | | Validate a service's inputs and outputs | provideService, consumeService | Optional wu-framework/services module |

For example, in an initialized trusted shell:

const stopListening = wu.on('catalog:selected', event => {
  console.log(event.data.productId);
});
wu.emit('catalog:selected', { productId: 'p-42' });

const stopLookup = wu.handle('catalog:lookup', ({ productId }) => ({
  productId, available: true,
}), { version: '1.0.0', allow: ['wu-core'] });

const result = await wu.request('catalog:lookup', { productId: 'p-42' }, {
  version: '^1', timeout: 3000,
});
console.log(result.available);
stopListening();
stopLookup();

Inside applications, use the scoped facade and matching manifest requests/host grants. Events use events.emit/events.subscribe; RPC uses rpc.call/rpc.provide. Provider allow lists independently constrain callers. Read the communication and state references before relying on wildcard subscriptions or replacement behavior.

Validated services and TypeScript inference

Version 3.1.0 adds an optional shared service definition used by the runtime, inferred clients and CLI tooling:

import { wu } from 'wu-framework';
import { schema as s, defineService, provideService, consumeService } from 'wu-framework/services';

const calculator = defineService({
  name: 'calculator',
  version: '1.0.0',
  methods: {
    add: {
      input: s.object({ left: s.number(), right: s.number() }),
      output: s.object({ sum: s.number() }),
    },
  },
});

// Run after the shell has initialized WU.
const provider = provideService(wu, calculator, {
  add({ left, right }) { return { sum: left + right }; },
}, { allow: ['wu-core'] });

const client = consumeService(wu, calculator);
const result = await client.add({ left: 2, right: 3 });
console.log(result.sum); // 5, inferred as number
provider.dispose();

Inputs and outputs are checked at provider and consumer boundaries. Schemas are frozen data with a documented subset of types; they do not run arbitrary validators or grant access. Compatibility checking conservatively flags changes to existing method schemas. Output validation happens after the implementation runs and cannot undo its effects.

See service schemas, errors and options. With CLI >=0.6.0, wu contracts types generates declarations from JSON definitions and wu contracts check compares revisions using this same module.

Workers, WASM and WASI

wu-framework/worker runs bounded jobs in fresh module Workers. It supports concurrency and queue limits, deadlines, cancellation, transferable ArrayBuffers, receipts and explicit disposal.

// compute.worker.js — build as a module Worker entry.
import { exposeWorker } from 'wu-framework/worker';
exposeWorker(({ text }) => ({ characters: [...text].length }));

The caller owns the service:

import { createWorkerService } from 'wu-framework/worker';

const worker = createWorkerService({
  workerUrl: '/workers/compute.js', // URL of the compiled Worker
  concurrency: 2,
  queueLimit: 8,
  timeoutMs: 3000,
  maxBytes: 65536,
});
try {
  const { value } = await worker.execute({ text: 'Hello WU' });
  console.log(value.characters); // 8
} finally {
  worker.dispose();
}

Connect worker.handle to WU RPC to expose the computation across applications. wu-framework/worker/wasi adds a bounded virtual filesystem and a documented WASI Preview 1 subset for compatible compiled guests. It provides no Node runtime, real filesystem or network imports. Run guests inside a Worker when CPU loops must be interruptible.

A browser Worker is not a security boundary for arbitrary same-origin JavaScript. Consult the Worker/WASI guide for the guest ABI, supported imports, byte/memory limits and cleanup contract.

Rendering, isolation and server integration

  • Shadow DOM: establishes a style boundary. DOM ownership and styleMode determine who creates and styles the root.
  • module: executes application modules in the host window.
  • strict and eval: use same-origin iframe mechanisms for coexistence and cleanup; they are not containment for hostile code.
  • SSR: wu-framework/server and server adapters provide rendering helpers. Client hydration depends on the renderer/integration, not just on server markup existing.
  • Astro: import WuApp.astro, WuAppSSR.astro or WuShell.astro from wu-framework/integrations/astro/…; perform browser mounting in a processed <script>, not server frontmatter.
  • Next: the integration exports WuApp, WuAppSSR, WuMount and WuShell under wu-framework/integrations/next/….
  • Routing: the shell owns page navigation. WU coordinates application lifecycles; metadata.routes is descriptive metadata.

See sandbox and style behavior, SSR and routing. Preserve framework-specific requirements instead of assuming every adapter has identical hydration or isolation behavior.

Debugging, testing and optional extensions

| Area | Entry points | | --- | --- | | Inspect an application | wu.getAppInfo, wu.getSandboxInfo, wu.getManifestDiagnostics | | Inspect runtime activity | wu.inspect, wu.getStats, wu.showInspector, wu.hideInspector | | Explain an RPC/contract failure | wu.explainRequest({ appName, channel, version, kind }) | | Prepare data for a support issue | wu.supportReport() — report-local aliases, counts and no store payloads | | Loading and overrides | Prefetch, loading strategies, URL overrides and error boundaries | | Extend lifecycle behavior | wu.hooks and wu.pluginSystem | | Optional state timeline | await wu.timelineReady() before recording | | Optional AI integrations | await wu.aiReady(); explicit providers, actions and permissions | | MCP integration | Bundled wu-mcp-server command and wu-framework/mcp-server subpath | | Lifecycle conformance | runLifecycleConformance from wu-framework/testing |

explainRequest does not invoke a handler or issue authority. supportReport() returns data locally and sends nothing. The conformance kit runs visible assertions and resource counters supplied by your fixture; it is not automatic whole-browser leak detection. Timeline replay does not reverse network calls or other external effects.

The AI/MCP subsystem is optional. Exposing an action does not authorize backend operations, and API keys should not be embedded in public client bundles. See extensions, MCP setup and security and quality tools.

Documentation map

| Guide | Covers | | --- | --- | | Overview | Runtime architecture and responsibilities | | Configuration | Host configuration, manifests and validation | | Lifecycle | Mount, update, teardown and keep-alive | | Loading | Entries, strategies, prefetch and overrides | | Communication | Events, RPC and object contracts | | Services | Schemas, inferred clients, errors and compatibility | | State | Paths, snapshots, batching and synchronization | | Integrations | Framework adapters and shell composition | | Sandbox | JavaScript modes, DOM ownership and styles | | SSR | Server rendering and hydration | | Security | Capability grants and trust boundaries | | Routing | Shell navigation and application ownership | | Extensions | Hooks, plugins, timeline, AI and MCP | | Worker/WASI | Background execution and portable guests | | Quality | Conformance, explanations and support reports | | Troubleshooting | Failed loads, mounts and diagnostics | | Public API | Methods, exports, types and compatibility notes |

Develop and verify the framework

Install both dependency trees before building from source:

npm ci --include=dev
npm ci --include=dev --prefix mcp-server
npm run build
npm run lint
npm test
npm run test:mcp
npm run test:package

build creates all distribution formats and the MCP executable. Rollup is a development dependency; publishing from an uninstalled checkout will fail. The MCP bundle also needs the mcp-server dependency tree. Package tests install the produced tarball and verify ESM, CommonJS, SSR, integrations, adapter imports and TypeScript.

For browser execution checks, install Playwright Chromium with npx playwright install chromium, then run npm run test:worker:browser. On machines with Edge, WU_BROWSER_CHANNEL=msedge selects that browser. See package.json for the current test scripts.

Team, support and license

Report a bug or suggest an improvement · Support independent development

Include package versions, a minimal reproduction, expected behavior and actual behavior in an issue. Review diagnostics before sharing them. WU Framework is MIT licensed.