# What is WU

Understand the problem WU solves, how an app and its shell fit together, and when using it makes sense.

See versions, changes and requirements in [Framework 4.0 and CLI 1.2](/docs/guides/releases/).


WU brings independent web applications together on one page. Each application keeps its interface and framework; WU coordinates when it appears, when it is removed, and how it communicates with the others.

The package includes adapters for **React, Vue, Angular, Svelte, Preact, Solid, Lit, Vanilla, Alpine, Qwik, Stencil, HTMX and Stimulus**. See their contracts in the [adapter reference](/docs/framework/api-adapters/).

For another technology, register `mount` and `unmount` with `wu.define`, or build an adapter with [`createWuAdapter`](/docs/framework/api-adapters/#createwuadapter). The common contract lets you connect applications using the same framework or different frameworks.

<span id="el-problema-que-resuelve"></span>

<span class="section-anchor" id="section-1"></span>

## The problem it solves

Imagine a store with a React catalog and a Vue cart. Their teams need to change and publish each part separately, while the user expects one experience: select a product in the catalog and see it in the cart.

WU loads both applications, gives each a container, and provides data-sharing channels. The catalog can announce a selection without importing cart components or code. Both applications could also use React: **application independence is the key; mixing frameworks is an option**.

<span id="tres-piezas-para-entenderlo"></span>

<span class="section-anchor" id="section-2"></span>

## Three pieces to understand

<span id="1-la-app-aporta-una-parte-de-la-interfaz"></span>

<span class="section-anchor" id="section-3"></span>

### 1. The app provides part of the interface

The catalog and cart are **microapps**, also called microfrontends or MFEs. Each registers how to render itself in a container and how to remove resources it created when leaving. In WU, these operations are `mount` and `unmount`: its lifecycle.

You can write them in JavaScript or use an **adapter**, which connects React, Vue, or another framework's lifecycle to WU. [Adapters](/docs/framework/api-adapters/) avoid repeating this connection in each application.

<span id="2-el-shell-decide-dónde-aparece-cada-app"></span>

<span class="section-anchor" id="section-4"></span>

### 2. The shell decides where each app appears

The **shell** or **host** is the page that brings them together. It defines their URLs, reserves spaces for display, and coordinates navigation, permissions, and visible errors. You can build it with Astro, another framework, or HTML and JavaScript.

In the store, the shell can reserve one area for the catalog and another for the cart. It does not need to know their internal components.

<span id="3-el-runtime-las-conecta-durante-la-ejecución"></span>

<span class="section-anchor" id="section-5"></span>

### 3. The runtime connects them during execution

The **runtime** is the `wu-framework` JavaScript package running on the page. It loads and mounts apps and provides events, shared state, and request/response calls.

For example, the catalog can emit an event when a product is selected; the cart receives it and updates its interface. The shell grants permissions needed by each app. Learn these mechanisms after your first mount, in [application communication](/docs/framework/communication/).

**WU CLI prepares the project.** The `wu` command runs in the terminal: it generates files, prepares dependencies, starts development, and assembles production files. The runtime works in the application opened by the user. You can use WU without the CLI if you prepare those files with your own tools. [Explore the CLI workflow](/docs/cli/overview/).

<span id="cuándo-tiene-sentido"></span>

<span class="section-anchor" id="section-6"></span>

## When it makes sense

- Different teams need to maintain and publish parts of one experience separately.
- You want to introduce a new application alongside an existing one during migration.
- You need to compose interfaces with style boundaries and explicit communication between applications.

If one application with its router and components meets your needs, splitting it into microapps adds configuration, mounting, and coordination work. You do not need several frameworks to use WU, or WU just because you use several components.

WU is also not a boundary for running hostile code. Shadow DOM encapsulates DOM and styles but does not itself prevent access to the page's JavaScript context. Read [isolation](/docs/framework/sandbox/) and [security and permissions](/docs/framework/security/) before choosing how to load third-party code.

<span id="empieza-con-una-app"></span>

<span class="section-anchor" id="section-7"></span>

## Start with one app

Follow [Your first app](/docs/guides/quickstart/) to generate a shell with a microapp and check the result in the browser. Then [add another app](/docs/guides/add-an-app/) and [prepare production](/docs/guides/production/).

The walkthrough uses Astro and React as an example. You may choose a different shell and frameworks.

<span id="qué-sucede-al-montar-una-app"></span>

<span class="section-anchor" id="section-8"></span>

## What happens when an app mounts

The shell declares the app URL. At that URL, a **manifest** (`wu.json`) describes the JavaScript file WU should load: its **entrypoint**. That file registers lifecycle; the shell requests mounting and the interface appears.

<details>
<summary>View a minimal JavaScript mount</summary>

This example shows the files involved. It assumes a project that resolves `import ... from 'wu-framework'` through its bundler and serves app files; it is not an installation recipe. [Your first app](/docs/guides/quickstart/) prepares that environment.

The shell HTML contains `<div id="hello-slot"></div>`. Its **client** module runs:

```js
import { wu } from 'wu-framework';

await wu.init({
  apps: [{ name: 'hello', url: '/apps/hello' }],
  sandbox: 'module',
});

await wu.mount('hello', '#hello-slot');
```

The URL serves `/apps/hello/wu.json`:

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

The `assets/hello.js` bundle registers the app when evaluated:

```js
import { wu } from 'wu-framework';

wu.define('hello', {
  mount(container) {
    const heading = document.createElement('h2');
    heading.textContent = 'Hola desde WU';
    container.append(heading);
  },
  unmount(container) {
    container.replaceChildren();
  },
});
```

When `wu.mount` resolves, the container displays **Hola desde WU**. `wu.define` registers how to render the app; `wu.mount` makes it appear. The name must match in the registration, manifest, and `define`. The entrypoint must be browser-usable JavaScript; publishing raw JSX/TSX on a static server does not turn it into an executable module.

<span id="una-instancia-compartida-y-permisos-por-app"></span>

<span class="section-anchor" id="section-9"></span>

### One shared instance and per-app permissions

The main import creates or reuses `window.wu` and also exposes `Symbol.for('wu-framework')`. Modules on the same page must resolve the runtime consistently; duplicating packages does not automatically produce isolated runtimes. In Node, importing `wu` still creates a module instance shared by that process: SSR uses `wu-framework/server` and per-request data.

The shell's imported `wu` has host authority. The second argument of the app's `mount(container, context)` callback contains `context.wu`: a **facade**, meaning WU access restricted to that application's permissions. It is revoked on unmount. Use this argument to preserve the permission contract. Retrieving `window.wu` from a microfrontend sharing the shell's JavaScript context retrieves host authority.

</details>

<span id="si-necesitas-profundizar"></span>

<span class="section-anchor" id="section-10"></span>

## For more detail

| What you want to understand | Continue here |
| --- | --- |
| Declaring apps, URLs, manifests, and permissions | [Configuration](/docs/framework/configuration/) |
| Mounting, unmounting, and cleaning resources | [Lifecycle](/docs/framework/lifecycle/) |
| Sending events or requesting another app's response | [Communication](/docs/framework/communication/) |
| Sharing data the interface can observe | [Shared state](/docs/framework/state/) |
| Finding a method's signature and contract | [API reference](/docs/framework/api-reference/) |
| Integrating Astro, Next, or server rendering | [Integrations](/docs/framework/integrations/) |

<details>
<summary>Explore technical limits and implementation sources</summary>

The package distributes ESM, CommonJS, and UMD and requires Node `>=20.0.0` for its tools. The browser runs the client runtime; the `wu-framework/server` entrypoint supplies server-rendering functions. Each adapter has its own renderer and hydration requirements.

WU does not require Astro to render React/Vue trees through its own islands: it can mount independent bundles in shell containers.

<span id="alcance-del-runtime"></span>

<span class="section-anchor" id="section-11"></span>

### Runtime scope

- There is no general core router interpreting manifest routes.
- Shadow DOM encapsulates DOM/CSS; it does not itself prevent access to the main window.
- `strict` and `eval` use same-origin iframes and are not a boundary against hostile code.
- The store, its history, and timeline live in memory; they provide neither a database nor durable auditing.
- Applications run in browser contexts; the core does not include a general driver, Worker, or WASM engine for arbitrary tasks.

<span id="referencia-de-implementación"></span>

<span class="section-anchor" id="section-12"></span>

### Implementation references

| Piece | Responsibility | Source |
| --- | --- | --- |
| `WuCore` | Registration, initialization, mounting, unmounting, and container ownership | `src/core/wu-core.js` |
| `wu.json` manifest | Entrypoint, exports, declarative dependencies, and requested permissions | `src/core/wu-manifest.js` |
| App lifecycle | Connect and remove its renderer from the supplied container | `src/index.d.ts` |
| Sandbox and style bridge | DOM boundary, style distribution, and effect tracking | `src/core/wu-sandbox.js` |
| Event bus and RPC | Events with identity; requests with response, version, and cancellation | `src/core/wu-event-bus.js` |
| Store | Shared data, separate snapshots, and notifications | `src/core/wu-store.js` |
| Shell | URLs, grants, navigation, composition, and visible error handling | `src/core/wu-core.js` |

The export contract is in `package.json`; singleton and global access in `src/index.js`; scoped context in `src/core/wu-core.js` and `src/core/wu-core.js`. Relevant tests include `tests/unit/package-exports.test.js`, `tests/unit/core-store-isolation.test.js`, and `tests/unit/capability-security-v3.test.js`.

</details>

See [supervision, recovery and replay](/docs/framework/runtime-reliability/) for `superviseApp`, `createReplaySession` and the scoped `reportError`, `now` and `random` methods.