Rstest

@module-federation/rstest enables Module Federation inside Rstest test builds. Use it when your tests should load real federated remotes instead of replacing the federation boundary with mocks.

Supports

  • Rstest Node and JSDOM test environments.
  • Rstest browser mode.
  • URL remotes such as remote@http://localhost:3001/remoteEntry.js.
  • commonjs ... path remotes for Node-based integration tests.
  • Automatic Rstest federation compatibility mode for Node-targeted test builds.

Requirements

Tip

Use @rstest/core@0.11.4 or newer. Rstest's federation support shipped in 0.11.4.

Rstest versions before 0.11.4 do not include the federation compatibility mode this plugin enables for Node test builds.

Quick Start

Installation

npm
yarn
pnpm
bun
npm add @module-federation/rstest @rstest/core --save-dev

Register Plugin

rstest.config.ts
import { federation } from '@module-federation/rstest';
import { defineConfig } from '@rstest/core';

export default defineConfig({
  plugins: [
    federation({
      name: 'host',
      remotes: {
        'component-app': 'component_app@http://localhost:3001/remoteEntry.js',
      },
      shared: {
        react: { singleton: true },
        'react-dom': { singleton: true },
      },
    }),
  ],
});
Warning

Do not set federation: true in rstest.config.ts when using this plugin. For Node and JSDOM test environments, @module-federation/rstest enables Rstest's federation compatibility mode automatically.

Run your tests with Rstest as usual:

npx rstest run

Reuse an Rsbuild Federation Configuration

When the test project already registers @module-federation/rsbuild-plugin, pass no options to federation():

rstest.config.ts
import {
  createModuleFederationConfig,
  pluginModuleFederation,
} from '@module-federation/rsbuild-plugin';
import { federation } from '@module-federation/rstest';
import { defineConfig } from '@rstest/core';

const options = createModuleFederationConfig({
  name: 'host',
  remotes: {
    'component-app': 'component_app@http://localhost:3001/remoteEntry.js',
  },
});

export default defineConfig({
  plugins: [
    pluginModuleFederation(options, {
      environment: 'rstest',
      target: 'node',
    }),
    federation(),
  ],
});

The plugin order is significant: register pluginModuleFederation first so federation() can normalize the same typed options. This creates one ModuleFederationPlugin and avoids duplicating the remote configuration.

Test a Federated Remote

Build or start the remote in Rstest's globalSetup, then import exposed modules the same way application code does:

remote.test.ts
import { expect, it } from '@rstest/core';
import Button from 'component-app/Button';

it('loads a remote through a static import', () => {
  expect(Button).toBeDefined();
});

it('loads a remote through a dynamic import', async () => {
  const remote = await import('component-app/Button');
  expect(remote.default).toBeDefined();
});

The official Rstest federation example combines an HTTP component remote with a locally built commonjs ... remote and runs both Node and JSDOM projects.

How It Works

For both Node and browser targets, dts, manifest, and dev default to false; explicit values are preserved.

Node Test Defaults

For Node-targeted Rstest builds, the plugin applies Module Federation defaults that match the Node runtime:

  • target: async-node
  • experiments.asyncStartup = true
  • CommonJS container output; module and modern-module library types are normalized
  • @module-federation/node/runtimePlugin
  • Node-targeted federation optimization
  • Script remote transport by default

Standard URL remotes use remoteType: 'script'. Inline transport prefixes such as commonjs ... override that default.

Browser Mode

Rstest browser mode is detected automatically from its resolved browser.enabled configuration:

Install @rstest/browser and a Playwright browser first. See Rstest's Browser Mode setup.

rstest.config.ts
import { federation } from '@module-federation/rstest';
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
  },
  plugins: [
    federation({
      name: 'browser_host',
      remotes: {
        app2: 'app2@http://localhost:3001/remoteEntry.js',
      },
    }),
  ],
});

Browser mode avoids node-only defaults while enabling experiments.asyncStartup and applying the shared defaults above. Pass an explicit target only to override the detected mode.

Configuration

federation(options, rstestOptions) accepts the standard Module Federation configuration as the first argument.

federation(moduleFederationOptions, {
  target: 'node', // or 'browser'
});

moduleFederationOptions

Module Federation Configuration

rstestOptions

  • Type: { target?: 'node' | 'browser' }
  • Default: auto-detected from Rstest's resolved browser.enabled configuration. Browser Mode defaults to 'browser'; other builds default to 'node'.

Producer Builds

Use @module-federation/rsbuild-plugin or another Module Federation build plugin to build the remote application. Use @module-federation/rstest only in the Rstest test project that consumes those remotes.

For Rsbuild producers, continue with the Rsbuild plugin guide.