> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# Rsbuild instance

This section describes all the properties and methods on the Rsbuild instance object.

## rsbuild.context

`rsbuild.context` is a read-only object that provides some context information, which can be accessed in two ways:

1. Access through the `context` property of the Rsbuild instance:

```ts
import { createRsbuild } from '@rsbuild/core';

const rsbuild = await createRsbuild({
  // ...
});

console.log(rsbuild.context);
```

2. Access through the [api.context](/plugins/dev/core.md#apicontext) of the Rsbuild plugin:

```ts
export const myPlugin = {
  name: 'my-plugin',
  setup(api) {
    console.log(api.context);
  },
};
```

### context.version

The version of `@rsbuild/core` currently in use.

- **Type:**

```ts
type Version = string;
```

### context.rootPath

The root path of the current build, corresponding to the `cwd` option of the [createRsbuild](/api/javascript-api/core.md#creatersbuild) method.

- **Type:**

```ts
type RootPath = string;
```

### context.configFile

The absolute path to the configuration file loaded by [loadConfig](/api/javascript-api/core.md#loadconfig). It is `undefined` when no configuration file is loaded.

- **Type:** `string | undefined`

### context.configFileDependencies

The absolute paths of files imported by the configuration file. The dependencies are collected by [loadConfig](/api/javascript-api/core.md#loadconfig).

- **Type:** `readonly string[]`
- **Default:** `[]`

### context.distPath

The absolute path of the output directory, corresponding to the [output.distPath.root](/config/output/dist-path.md) config in `RsbuildConfig`.

When multiple environments exist, Rsbuild attempts to find the parent distPath of all environments as `context.distPath`.

To get the absolute path to a specific environment's output directory, use [environment.distPath](/api/javascript-api/environment-api.md#distpath).

- **Type:**

```ts
type DistPath = string;
```

### context.cachePath

The absolute path of the build cache files.

- **Type:**

```ts
type CachePath = string;
```

### context.callerName

The name of the framework or tool that is currently invoking Rsbuild, the same as the [callerName](/api/javascript-api/core.md#specify-caller-name) option in the [createRsbuild](/api/javascript-api/core.md#creatersbuild) method.

- **Type:** `string`
- **Default:** `'rsbuild'`
- **Example:**

```ts title="myPlugin.ts"
export const myPlugin = {
  name: 'my-plugin',
  setup(api) {
    const { callerName } = api.context;

    if (callerName === 'rslib') {
      // ...
    } else if (callerName === 'rsbuild') {
      // ...
    }
  },
};
```

Here are some tools based on Rsbuild that have already set the `callerName` value:

| Name                                                | callerName  |
| --------------------------------------------------- | ----------- |
| [Rslib](https://github.com/web-infra-dev/rslib)     | `'rslib'`   |
| [Rstest](https://github.com/web-infra-dev/rstest)   | `'rstest'`  |
| [Rspress](https://github.com/web-infra-dev/rspress) | `'rspress'` |
| [Rspeedy](https://lynxjs.org/rspeedy)               | `'rspeedy'` |

### context.devServer

Dev server information when running in dev mode. Available after the dev server has been created.

- **Type:**

```ts
type DevServer = {
  /** The hostname the server is running on. */
  hostname: string;
  /** The actual port number the server is listening on. */
  port: number;
  /** Whether the server is using HTTPS protocol. */
  https: boolean;
};
```

- **Example:**

```ts
import { createRsbuild } from '@rsbuild/core';

async function main() {
  const rsbuild = await createRsbuild({
    // ...
  });
  await rsbuild.startDevServer();

  // { hostname: 'localhost', port: 3000, https: false }
  console.log(rsbuild.context.devServer);
}
```

### context.action

The current action type.

- **Type:**

```ts
type Action = 'dev' | 'build' | 'preview' | undefined;
```

`context.action` is set when running CLI commands or calling Rsbuild instance methods:

- `dev`: set when running [rsbuild dev](/guide/basic/cli.md#rsbuild) or [rsbuild.startDevServer()](/api/javascript-api/instance.md#rsbuildstartdevserver)
- `build`: set when running [rsbuild build](/guide/basic/cli.md#rsbuild-build) or [rsbuild.build()](/api/javascript-api/instance.md#rsbuildbuild)
- `preview`: set when running [rsbuild preview](/guide/basic/cli.md#rsbuild-preview) or [rsbuild.preview()](/api/javascript-api/instance.md#rsbuildpreview)

For example:

```ts
if (rsbuild.context.action === 'dev') {
  // do something
}
```

## rsbuild.logger

`rsbuild.logger` is the logger associated with the current Rsbuild instance. See [Logging](/guide/advanced/logging.md) for more details.

- **Type:** [Logger](/api/javascript-api/core.md#logger)

- **Example:**

```ts
const rsbuild = await createRsbuild();

rsbuild.logger.info('build started');
```

## rsbuild.build

Runs a production build, generating optimized production bundles and writing them to the output directory.

- **Type:**

```ts
type BuildOptions = {
  /**
   * Whether to watch for file changes and rebuild.
   * @default false
   */
  watch?: boolean;
};

function Build(options?: BuildOptions): Promise<{
  /**
   * Rspack's [stats](https://rspack.rs/api/javascript-api/stats) object.
   */
  stats?: Rspack.Stats | Rspack.MultiStats;
  /**
   * Close the build and call the `onCloseBuild` hook.
   * In watch mode, this method will stop watching.
   */
  close: () => Promise<void>;
}>;
```

- **Example:**

```ts
import { logger } from '@rsbuild/core';

// Example 1: run build
await rsbuild.build();

// Example 2: build and handle the error
try {
  await rsbuild.build();
} catch (err) {
  logger.error('Failed to build.');
  logger.error(err);
  process.exit(1);
}

// Example 3: build and get all assets
const { stats } = await rsbuild.build();

if (stats) {
  const { assets } = stats.toJson({
    // exclude unused fields to improve performance
    all: false,
    assets: true,
  });
  console.log(assets);
}
```

### Monitor file changes

To watch file changes and re-build, set the `watch` option to `true`.

```ts
await rsbuild.build({
  watch: true,
});
```

### Close build

`rsbuild.build()` returns a `close()` method that stops the build process.

In watch mode, calling the `close()` method will stop watching:

```ts
const buildResult = await rsbuild.build({
  watch: true,
});
await buildResult.close();
```

In non-watch mode, also call the `close()` method to end the build, which triggers the [onCloseBuild](/plugins/dev/hooks.md#onclosebuild) hook for cleanup operations.

```ts
const buildResult = await rsbuild.build();
await buildResult.close();
```

### Stats object

In non-watch mode, `rsbuild.build()` returns an Rspack [stats](https://rspack.rs/api/javascript-api/stats) object.

For example, use the `stats.toJson()` method to get asset information:

```ts
const result = await rsbuild.build();
const { stats } = result;

if (stats) {
  const { assets } = stats.toJson({
    // exclude unused fields to improve performance
    all: false,
    assets: true,
  });
  console.log(assets);
}
```

## rsbuild.startDevServer

Starts the local dev server. This method will:

1. Start a development server to serve your application
2. Watch for file changes and trigger recompilation

- **Type:**

```ts
type StartDevServerOptions = {
  /**
   * Whether to get port silently and not print any logs.
   * @default false
   */
  getPortSilently?: boolean;
};

type StartDevServerResult = {
  /**
   * The URLs that server is listening on.
   */
  urls: string[];
  /**
   * The actual port used by the server.
   */
  port: number;
  server: RsbuildDevServer;
};

function StartDevServer(
  options?: StartDevServerOptions,
): Promise<StartDevServerResult>;
```

- **Example:**

Start dev server:

```ts
import { logger } from '@rsbuild/core';

// Start dev server
await rsbuild.startDevServer();

// Start dev server and handle the error
try {
  await rsbuild.startDevServer();
} catch (err) {
  logger.error('Failed to start dev server.');
  logger.error(err);
  process.exit(1);
}
```

Once the dev server starts successfully, these logs appear:

```
  ➜  Local:    http://localhost:3000
  ➜  Network:  use --host to expose
```

`startDevServer` returns these parameters:

- `urls`: URLs to access dev server.
- `port`: The actual listening port number.
- `server`: Server instance, see [Server API](/api/javascript-api/server-api.md) for more details.

```ts
const { urls, port } = await rsbuild.startDevServer();
console.log(urls); // ['http://localhost:3000', 'http://192.168.0.1:3000']
console.log(port); // 3000
```

### Close server

Call the `server.close()` method to close the dev server, trigger the [onCloseDevServer](/plugins/dev/hooks.md#onclosedevserver) hook, and perform cleanup operations.

```ts
const { server } = await rsbuild.startDevServer();
await server.close();
```

### Get port silently

When the default startup port is occupied, Rsbuild automatically increments the port number until it finds an available one. This process outputs a prompt log. To suppress this log, set `getPortSilently` to `true`.

```ts
await rsbuild.startDevServer({
  getPortSilently: true,
});
```

## rsbuild.createDevServer

- **Type:**

```ts
type CreateDevServerOptions = {
  /**
   * Whether to get port silently and not print any logs.
   * @default false
   */
  getPortSilently?: boolean;
  /**
   * Whether to trigger Rsbuild compilation
   * @default true
   */
  runCompile?: boolean;
};

function createDevServer(
  options?: CreateDevServerOptions,
): Promise<RsbuildDevServer>;
```

Rsbuild includes a built-in dev server designed to improve the development experience. When you run the `rsbuild dev` command, the server starts automatically and provides features such as page preview, routing, and hot module reloading.

- To integrate the Rsbuild dev server into a custom server, you can use the `createDevServer` method to create a dev server instance. Refer to [Server API](/api/javascript-api/server-api.md) for all available APIs.
- To use Rsbuild dev server to start the project directly, you can use the [rsbuild.startDevServer](#rsbuildstartdevserver) method directly. `rsbuild.startDevServer` is actually syntactic sugar for the following code:

```ts
const server = await rsbuild.createDevServer();
await server.listen();
```

## rsbuild.preview

Starts a server to preview the production build locally. This method should be executed after [rsbuild.build](#rsbuildbuild).

- **Type:**

```ts
type PreviewOptions = {
  /**
   * Whether to get port silently
   * @default false
   */
  getPortSilently?: boolean;
  /**
   * Whether to check if the dist directory exists and is not empty.
   * @default true
   */
  checkDistDir?: boolean;
};

type StartPreviewServerResult = {
  /**
   * The URLs that server is listening on.
   */
  urls: string[];
  /**
   * The actual port used by the server.
   */
  port: number;
  server: RsbuildPreviewServer;
};

function preview(options?: PreviewOptions): Promise<StartPreviewServerResult>;
```

- **Example:**

Start the server:

```ts
import { logger } from '@rsbuild/core';

// Start preview server
await rsbuild.preview();

// Start preview server and handle the error
try {
  await rsbuild.preview();
} catch (err) {
  logger.error('Failed to start preview server.');
  logger.error(err);
  process.exit(1);
}
```

`preview` returns the following parameters:

- `urls`: URLs to access server.
- `port`: The actual listening port number.
- `server`: Server instance, see [Server API](/api/javascript-api/server-api.md) for more details.

```ts
const { urls, port } = await rsbuild.preview();
console.log(urls); // ['http://localhost:3000', 'http://192.168.0.1:3000']
console.log(port); // 3000
```

### Close server

Calling the `close()` method will close the preview server.

```ts
const { server } = await rsbuild.preview();
await server.close();
```

## rsbuild.createCompiler

Creates an Rspack [Compiler](https://rspack.rs/api/javascript-api/compiler) instance. If there are multiple [environments](/config/environments.md) for this build, the return value is [MultiCompiler](https://rspack.rs/api/javascript-api/compiler#multicompiler).

- **Type:**

```ts
function CreateCompiler(): Promise<Compiler | MultiCompiler>;
```

- **Example:**

```ts
const compiler = await rsbuild.createCompiler();
```

> You do not need to use this API unless you need to custom the dev server or other advanced scenarios.

## rsbuild.addPlugins

Registers one or more Rsbuild plugins, which can be called multiple times.

This method needs to be called before compiling. If it is called after compiling, it will not affect the compilation result.

- **Type:**

```ts
type AddPluginsOptions = { before?: string; environment?: string };

function AddPlugins(
  plugins: Array<RsbuildPlugin | Falsy>,
  options?: AddPluginsOptions,
): void;
```

- **Example:**

```ts
rsbuild.addPlugins([pluginFoo(), pluginBar()]);

// Insert before the bar plugin
rsbuild.addPlugins([pluginFoo()], { before: 'bar' });

// Add plugin for node environment
rsbuild.addPlugins([pluginFoo()], { environment: 'node' });
```

## rsbuild.getPlugins

Gets all the Rsbuild plugins registered in the current Rsbuild instance.

- **Type:**

```ts
function GetPlugins(options?: {
  /**
   * Get the plugins in the specified environment.
   * If environment is not specified, get the global plugins.
   */
  environment: string;
}): RsbuildPlugin[];
```

- **Example:**

```ts
// get all plugins
console.log(rsbuild.getPlugins());

// get plugins in `web` environment
console.log(rsbuild.getPlugins({ environment: 'web' }));
```

## rsbuild.removePlugins

Removes one or more Rsbuild plugins, which can be called multiple times.

This method needs to be called before compiling. If it is called after compiling, it will not affect the compilation result.

- **Type:**

```ts
function RemovePlugins(
  pluginNames: string[],
  options?: {
    /**
     * Remove the plugin in the specified environment.
     * If environment is not specified, remove it in all environments.
     */
    environment?: string;
  },
): void;
```

- **Example:**

```ts
// add plugin
const foo = pluginFoo();
rsbuild.addPlugins([foo]);

// remove plugin
rsbuild.removePlugins([foo.name]);
```

## rsbuild.isPluginExists

Determines if a plugin has been registered in the current Rsbuild instance.

- If the `environment` parameter is not specified, it checks if the plugin exists in the globally registered plugins.

- If the `environment` parameter is specified, it checks if the plugin exists in the specified environment.

- **Type:**

```ts
function IsPluginExists(
  pluginName: string,
  options?: {
    /**
     * Whether it exists in the specified environment.
     * If environment is not specified, determine whether the plugin is a global plugin.
     */
    environment: string;
  },
): boolean;
```

- **Example:**

```ts
const pluginFoo = {
  name: 'plugin-foo',
  setup(api) {
    // ...
  },
};

const rsbuild = await createRsbuild({
  config: {
    plugins: [pluginFoo],
  },
});

rsbuild.isPluginExists(pluginFoo.name); // true
```

Or check if a plugin exists in a specified environment:

```ts
const rsbuild = await createRsbuild({
  config: {
    environments: {
      web: {
        plugins: [pluginFoo],
      },
    },
  },
});

rsbuild.isPluginExists(pluginFoo.name, {
  environment: 'web',
}); // true
```

## rsbuild.initConfigs

Initialize and return the internal Rspack configurations used by Rsbuild. This method processes all plugins and configurations to generate the final Rspack configs.

> Note: You typically do not need to call this method directly since it is automatically invoked by methods like [rsbuild.build](#rsbuildbuild) and [rsbuild.startDevServer](#rsbuildstartdevserver).

- **Type:**

```ts
type InitConfigsOptions = {
  /**
   * The current action type.
   * - dev: will be set when running `rsbuild dev` or `rsbuild.startDevServer()`
   * - build: will be set when running `rsbuild build` or `rsbuild.build()`
   * - preview: will be set when running `rsbuild preview` or `rsbuild.preview()`
   */
  action?: 'dev' | 'build' | 'preview';
};

function InitConfigs(
  options?: InitConfigsOptions,
): Promise<Rspack.Configuration[]>;
```

- **Example:**

```ts
const rspackConfigs = await rsbuild.initConfigs();

console.log(rspackConfigs);

const buildConfigs = await rsbuild.initConfigs({
  action: 'build',
});

console.log(buildConfigs);
```

## rsbuild.inspectConfig

Inspects and debugs Rsbuild's internal configurations. It provides access to:

- The resolved Rsbuild configuration
- The environment-specific Rsbuild configurations
- The generated Rspack configurations

The method serializes these configurations to strings and optionally writes them to disk for inspection.

- **Type:**

```ts
type InspectConfigOptions = {
  /**
   * Inspect the config in the specified mode.
   * Available options: 'development', 'production', or 'none'.
   * @default Inferred from `process.env.NODE_ENV`: 'development' when unset,
   * 'development' or 'production' when matching, otherwise 'none'.
   */
  mode?: RsbuildMode;
  /**
   * Enables verbose mode to display the complete function
   * content in the configuration.
   * @default false
   */
  verbose?: boolean;
  /**
   * Specify the output path for inspection results.
   * @default '<context.distPath>/.rsbuild'
   */
  outputPath?: string;
  /**
   * Whether to write the inspection results to disk.
   * @default false
   */
  writeToDisk?: boolean;
  /**
   * Extra configurations to be output.
   * - key: The name of the configuration
   * - value: The configuration object
   */
  extraConfigs?: Record<string, unknown>;
};

async function InspectConfig(options?: InspectConfigOptions): Promise<{
  rsbuildConfig: string;
  bundlerConfigs: string[];
  environmentConfigs: string[];
  origin: {
    rsbuildConfig: Omit<NormalizedConfig, 'environments'>;
    environmentConfigs: Record<string, NormalizedEnvironmentConfig>;
    bundlerConfigs: Rspack.Configuration[];
  };
}>;
```

:::tip
To view the Rsbuild and Rspack configurations during the build process, use [debug mode](/guide/debug/debug-mode.md), or obtain them through hooks such as [onBeforeBuild](#rsbuildonbeforebuild), [onBeforeCreateCompiler](#rsbuildonbeforecreatecompiler).
:::

### Example

Get the content of configs in string format:

```ts
const { rsbuildConfig, bundlerConfigs } = await rsbuild.inspectConfig();

console.log(rsbuildConfig, bundlerConfigs);
```

Write the config content to disk:

```ts
await rsbuild.inspectConfig({
  writeToDisk: true,
});
```

### Output path

You can set the output path using `outputPath`. By default, the files are written to the `.rsbuild` directory under [context.distPath](#contextdistpath).

If `outputPath` is a relative path, it will be resolved relative to `context.distPath`. You can also set `outputPath` to an absolute path, in which case the files will be written directly to that path. For example:

```ts
import path from 'node:path';

await rsbuild.inspectConfig({
  writeToDisk: true,
  outputPath: path.join(__dirname, 'custom-dir'),
});
```

## rsbuild.onBeforeCreateCompiler

> Provides the same functionality as the [onBeforeCreateCompiler](/plugins/dev/hooks.md#onbeforecreatecompiler) plugin hook.

A callback function that is triggered before the Rspack Compiler instance is created. This hook is called when you run `rsbuild.startDevServer`, `rsbuild.build`, or `rsbuild.createCompiler`.

You can access the Rspack configuration array through the `bundlerConfigs` parameter. The array may contain one or more [Rspack configurations](https://rspack.rs/config/). It depends on whether multiple [environments](/config/environments.md) are configured.

- **Type:**

```ts
function OnBeforeCreateCompiler(
  callback: (params: {
    bundlerConfigs: Rspack.Configuration[];
    environments: Record<string, EnvironmentContext>;
  }) => Promise<void> | void,
): void;
```

- **Example:**

```ts
rsbuild.onBeforeCreateCompiler(({ bundlerConfigs }) => {
  console.log('the Rspack config is ', bundlerConfigs);
});
```

## rsbuild.onAfterCreateCompiler

> Provides the same functionality as the [onAfterCreateCompiler](/plugins/dev/hooks.md#onaftercreatecompiler) plugin hook.

A callback function that is triggered after the Rspack Compiler instance has been created, but before the build process. This hook is called when you run `rsbuild.startDevServer`, `rsbuild.build`, or `rsbuild.createCompiler`.

You can access the [Compiler instance](https://rspack.rs/api/javascript-api/compiler) through the `compiler` parameter:

- **Type:**

```ts
function OnAfterCreateCompiler(
  callback: (params: {
    compiler: Compiler | MultiCompiler;
    environments: Record<string, EnvironmentContext>;
  }) => Promise<void> | void,
): void;
```

- **Example:**

```ts
rsbuild.onAfterCreateCompiler(({ compiler }) => {
  console.log('the compiler is ', compiler);
});
```

## rsbuild.onBeforeBuild

> Provides the same functionality as the [onBeforeBuild](/plugins/dev/hooks.md#onbeforebuild) plugin hook.

A callback function that is triggered before the production build is executed.

You can access the Rspack configuration array through the `bundlerConfigs` parameter. The array may contain one or more [Rspack configurations](https://rspack.rs/config/). It depends on whether multiple [environments](/config/environments.md) are configured.

Moreover, you can use `isWatch` to determine whether it is watch mode, and use `isFirstCompile` to determine whether it is the first build on watch mode.

- **Type:**

```ts
function OnBeforeBuild(
  callback: (params: {
    isWatch: boolean;
    isFirstCompile: boolean;
    bundlerConfigs?: Rspack.Configuration[];
    environments: Record<string, EnvironmentContext>;
  }) => Promise<void> | void,
): void;
```

- **Example:**

```ts
rsbuild.onBeforeBuild(({ bundlerConfigs }) => {
  console.log('the Rspack config is ', bundlerConfigs);
});
```

## rsbuild.onAfterBuild

> Provides the same functionality as the [onAfterBuild](/plugins/dev/hooks.md#onafterbuild) plugin hook.

A callback function that is triggered after running the production build. You can access the build result information via the [stats](https://rspack.rs/api/javascript-api/stats) parameter.

Moreover, you can use `isWatch` to determine whether it is watch mode, and use `isFirstCompile` to determine whether it is the first build on watch mode.

- **Type:**

```ts
function OnAfterBuild(
  callback: (params: {
    isFirstCompile: boolean;
    isWatch: boolean;
    stats?: Stats | MultiStats;
    environments: Record<string, EnvironmentContext>;
  }) => Promise<void> | void,
): void;
```

- **Example:**

```ts
rsbuild.onAfterBuild(({ stats }) => {
  console.log(stats?.toJson());
});
```

## rsbuild.onCloseBuild

> Provides the same functionality as the [onCloseBuild](/plugins/dev/hooks.md#onclosebuild) plugin hook.

Called when closing the build instance. Can be used to perform cleanup operations when the building is closed.

Rsbuild CLI will automatically call this hook after running [rsbuild build](/guide/basic/cli.md#rsbuild-build), while users of the JavaScript API need to manually call the [build.close()](/api/javascript-api/instance.md#close-build) method to trigger this hook.

- **Type:**

```ts
function onCloseBuild(callback: () => Promise<void> | void): void;
```

- **Example:**

```ts
rsbuild.onCloseBuild(async () => {
  console.log('close build!');
});
```

## rsbuild.onBeforeStartDevServer

> Provides the same functionality as the [onBeforeStartDevServer](/plugins/dev/hooks.md#onbeforestartdevserver) plugin hook.

Called before starting the dev server.

Use the `server` parameter to get the dev server instance, see [Server API](/api/javascript-api/server-api.md) for more information.

- **Type:**

```ts
type MaybePromise<T> = T | Promise<T>;

type OnBeforeStartDevServerFn = (params: {
  /**
   * The dev server instance, the same as the return value of `createDevServer`.
   */
  server: RsbuildDevServer;
  /**
   * Context information for all environments.
   */
  environments: Record<string, EnvironmentContext>;
}) => MaybePromise<(() => MaybePromise<void>) | void>;

function OnBeforeStartDevServer(callback: OnBeforeStartDevServerFn): void;
```

- **Example:**

```ts
rsbuild.onBeforeStartDevServer(({ server, environments }) => {
  console.log('before starting dev server.');
  console.log('the server is ', server);
  console.log('the environments contexts are: ', environments);
});
```

> See [Plugin hooks - onBeforeStartDevServer](/plugins/dev/hooks.md#onbeforestartdevserver) for more details.

## rsbuild.onAfterStartDevServer

> Provides the same functionality as the [onAfterStartDevServer](/plugins/dev/hooks.md#onafterstartdevserver) plugin hook.

Called after starting the dev server, you can get the port number with the `port` parameter, and the page routes info with the `routes` parameter.

- **Type:**

```ts
type ReadonlyRoutes = ReadonlyArray<{
  readonly entryName: string;
  readonly pathname: string;
}>;

function OnAfterStartDevServer(
  callback: (params: {
    port: number;
    routes: ReadonlyRoutes;
    environments: Record<string, EnvironmentContext>;
  }) => Promise<void> | void,
): void;
```

- **Example:**

```ts
rsbuild.onAfterStartDevServer(({ port, routes }) => {
  console.log('this port is: ', port);
  console.log('this routes is: ', routes);
});
```

## rsbuild.onCloseDevServer

> Provides the same functionality as the [onCloseDevServer](/plugins/dev/hooks.md#onclosedevserver) plugin hook.

Called when closing the dev server. Can be used to perform cleanup operations when the dev server is closed.

Rsbuild CLI will automatically call this hook at the appropriate time, while users of the JavaScript API need to manually call the [server.close()](/api/javascript-api/instance.md#close-server) method to trigger this hook.

- **Type:**

```ts
function onCloseDevServer(callback: () => Promise<void> | void): void;
```

- **Example:**

```ts
rsbuild.onCloseDevServer(async () => {
  console.log('close dev server!');
});
```

## rsbuild.onBeforeStartPreviewServer

> Provides the same functionality as the [onBeforeStartPreviewServer](/plugins/dev/hooks.md#onbeforestartpreviewserver) plugin hook.

Called before starting the preview server.

Use the `server` parameter to access the preview server and register custom middlewares.

- **Type:**

```ts
type MaybePromise<T> = T | Promise<T>;

type OnBeforeStartPreviewServerFn = (params: {
  /**
   * The preview server instance.
   */
  server: RsbuildPreviewServer;
  /**
   * Context information for all environments.
   */
  environments: Record<string, EnvironmentContext>;
}) => MaybePromise<void>;

function OnBeforeStartPreviewServer(
  callback: OnBeforeStartPreviewServerFn,
): void;
```

- **Example:**

```ts
rsbuild.onBeforeStartPreviewServer(({ server, environments }) => {
  console.log('before start!');
  console.log('the server is ', server);
  console.log('the environments contexts are: ', environments);
});
```

## rsbuild.onAfterStartPreviewServer

> Provides the same functionality as the [onAfterStartPreviewServer](/plugins/dev/hooks.md#onafterstartpreviewserver) plugin hook.

Called after starting the preview server, you can get the port number with the `port` parameter, and the page routes info with the `routes` parameter.

- **Type:**

```ts
type ReadonlyRoutes = ReadonlyArray<{
  readonly entryName: string;
  readonly pathname: string;
}>;

function OnAfterStartPreviewServer(
  callback: (params: {
    port: number;
    routes: ReadonlyRoutes;
    environments: Record<string, EnvironmentContext>;
  }) => Promise<void> | void,
): void;
```

- **Example:**

```ts
rsbuild.onAfterStartPreviewServer(({ port, routes }) => {
  console.log('this port is: ', port);
  console.log('this routes is: ', routes);
});
```

## rsbuild.onBeforeDevCompile

> Provides the same functionality as the [onBeforeDevCompile](/plugins/dev/hooks.md#onbeforedevcompile) plugin hook.

A callback function that is triggered before the dev compile is executed.

You can access the Rspack configuration array through the `bundlerConfigs` parameter. The array may contain one or more [Rspack configurations](https://rspack.rs/config/). It depends on whether multiple [environments](/config/environments.md) are configured.

Moreover, you can use `isFirstCompile` to determine whether it is the first compile.

- **Type:**

```ts
function OnBeforeDevCompile(
  callback: (params: {
    isWatch: boolean;
    isFirstCompile: boolean;
    bundlerConfigs?: Rspack.Configuration[];
    environments: Record<string, EnvironmentContext>;
  }) => Promise<void> | void,
): void;
```

- **Version:** Added in v1.5.0

- **Example:**

```ts
rsbuild.onBeforeDevCompile(({ bundlerConfigs }) => {
  console.log('the Rspack configs are ', bundlerConfigs);
});
```

## rsbuild.onAfterDevCompile

> Provides the same functionality as the [onAfterDevCompile](/plugins/dev/hooks.md#onafterdevcompile) plugin hook.

Called after each development mode build, you can use `isFirstCompile` to determine whether it is the first build.

- **Type:**

```ts
function OnAfterDevCompile(
  callback: (params: {
    isFirstCompile: boolean;
    stats: Stats | MultiStats;
    environments: Record<string, EnvironmentContext>;
  }) => Promise<void> | void,
): void;
```

:::tip
The `onAfterDevCompile` hook was added in Rsbuild v1.5.0. For earlier versions, you can use the functionally identical `onDevCompileDone` hook.
:::

- **Example:**

```ts
rsbuild.onAfterDevCompile(({ isFirstCompile }) => {
  if (isFirstCompile) {
    console.log('first compile!');
  } else {
    console.log('re-compile!');
  }
});
```

## rsbuild.onBeforeEnvironmentCompile

> Provides the same functionality as the [onBeforeEnvironmentCompile](/plugins/dev/hooks.md#onbeforeenvironmentcompile) plugin hook.

- **Version:** Added in v1.5.7
- **Example:**

```ts
rsbuild.onBeforeEnvironmentCompile(({ bundlerConfig, environment }) => {
  console.log(
    `the bundler config for the ${environment.name} is `,
    bundlerConfig,
  );
});
```

## rsbuild.onAfterEnvironmentCompile

> Provides the same functionality as the [onAfterEnvironmentCompile](/plugins/dev/hooks.md#onafterenvironmentcompile) plugin hook.

- **Version:** Added in v1.5.7
- **Example:**

```ts
rsbuild.onAfterEnvironmentCompile(({ isFirstCompile, stats }) => {
  console.log(stats?.toJson(), isFirstCompile);
});
```

## rsbuild.onRestart

> Provides the same functionality as the [onRestart](/plugins/dev/hooks.md#onrestart) plugin hook.

Called when a restart is requested for the dev server or watch build.

The hook is triggered in the following cases:

- The Rsbuild CLI detects changes to the config file or one of its dependencies.
- A configured file event occurs for a file watched by [`dev.watchFiles`](/config/dev/watch-files.md) with `type: 'restart'`.
- The dev server is manually restarted through a [CLI shortcut](/config/dev/cli-shortcuts.md).

> This hook is not triggered for regular rebuilds.

When using the JavaScript API, restart watchers are installed by `rsbuild.startDevServer()`, `rsbuild.createDevServer()`, and `rsbuild.build({ watch: true })`. The hook is called when a configured file event occurs. By default, Rsbuild does not close or restart the current task; you can pass the [`restart` option](/api/javascript-api/core.md#restart-handling) to handle restart requests.

- **Type:**

```ts
type WatchFileEvent = 'add' | 'change' | 'unlink';

type RestartContext = {
  filePath?: string;
  event?: WatchFileEvent;
} & (
  | {
      action: 'build';
      options: BuildOptions;
    }
  | {
      action: 'dev';
      options: StartDevServerOptions;
    }
);

function OnRestart(
  callback: (context: RestartContext) => Promise<void> | void,
): void;
```

- `action`: The current Rsbuild action being restarted.

- `filePath`: The absolute path of the file that triggered the restart. It is `undefined` when the restart is manually triggered.

- `event`: The file event that triggered the restart. It is `undefined` when the restart is manually triggered. Available in v2.1.8 or later.

- `options`: The options passed to the current `rsbuild.build()` or `rsbuild.startDevServer()` call.

- **Version:** Added in v2.1.7

- **Example:**

```ts
rsbuild.onRestart(async ({ action, filePath }) => {
  console.log('restart!', action, filePath);
});
```

## rsbuild.onExit

> Provides the same functionality as the [onExit](/plugins/dev/hooks.md#onexit) plugin hook.

Called when the process is going to exit, this hook can only execute synchronous code.

- **Type:**

```ts
function OnExit(callback: (context: { exitCode: number }) => void): void;
```

- **Example:**

```ts
rsbuild.onExit(({ exitCode }) => {
  console.log('exit: ', exitCode);
});
```

## rsbuild.getRsbuildConfig

> Provides the same functionality as the [getRsbuildConfig](/plugins/dev/core.md#apigetrsbuildconfig) plugin API.

Get the Rsbuild config, this method must be called after the `modifyRsbuildConfig` hook is executed.

- **Type:**

```ts
type GetRsbuildConfig = {
  (): Readonly<RsbuildConfig>;
  (type: 'original' | 'current'): Readonly<RsbuildConfig>;
  (type: 'normalized'): NormalizedConfig;
};
```

- **Parameters:**

You can specify the type of Rsbuild config to read by using the `type` parameter:

```js
// Get the original Rsbuild config defined by the user.
getRsbuildConfig('original');

// Get the current Rsbuild config.
// The content of this config will change at different execution stages of Rsbuild.
// For example, the content of the current Rsbuild config will be modified after running the `modifyRsbuildConfig` hook.
getRsbuildConfig('current');

// Get the normalized Rsbuild config.
// This method must be called after the `modifyRsbuildConfig` hook has been executed.
// It is equivalent to the `getNormalizedConfig` method.
getRsbuildConfig('normalized');
```

- **Example:**

```ts
rsbuild.onBeforeBuild(() => {
  const config = rsbuild.getRsbuildConfig();
  console.log(config.html?.title);
});
```

## rsbuild.getNormalizedConfig

> Provides the same functionality as the [getNormalizedConfig](/plugins/dev/core.md#apigetnormalizedconfig) plugin API.

Returns either the complete normalized Rsbuild config, including all environments, or the normalized config for a specific environment. You can call this method only after the [modifyRsbuildConfig](/plugins/dev/hooks.md#modifyrsbuildconfig) hook has completed.

Unlike [`getRsbuildConfig`](/plugins/dev/core.md#apigetrsbuildconfig), this method returns a normalized config with narrower types. For example, the type of `config.html` no longer includes `undefined`.

Use `getNormalizedConfig()` to get the complete config, including all environments. To get the config for a specific environment, use `getNormalizedConfig({ environment: name })`.

- **Type:**

```ts
type GetNormalizedConfig = {
  /** Get the complete normalized config, including all environments */
  (): NormalizedConfig;
  /** Get the normalized config for a specific environment */
  (options: { environment: string }): NormalizedEnvironmentConfig;
};
```

- **Example:**

```ts
rsbuild.onBeforeBuild(() => {
  const config = rsbuild.getNormalizedConfig();
  console.log(config.html.title);
});
```

## rsbuild.expose

> Provides the same functionality as the [expose](/plugins/dev/core.md#apiexpose) plugin API.

- **Version:** Added in v1.5.0
- **Example:**

```ts
rsbuild.expose('my-id', {
  value: 1,
  double: (val: number) => val * 2,
});
```

You can also expose an API for a specific Rsbuild environment (the key of `config.environments`):

```ts
rsbuild.expose(
  'my-id',
  {
    value: 1,
    double: (val: number) => val * 2,
  },
  {
    environment: 'web',
  },
);
```

When a plugin registered in the same environment calls `api.useExposed`, Rsbuild will first resolve the environment-scoped API, then fall back to the global API.

## rsbuild.modifyRsbuildConfig

> Provides the same functionality as the [modifyRsbuildConfig](/plugins/dev/hooks.md#modifyrsbuildconfig) plugin API.

- **Version:** Added in v1.5.0
- **Example:**

```ts
rsbuild.modifyRsbuildConfig((config) => {
  config.html ||= {};
  config.html.title = 'My Default Title';
});
```

## rsbuild.modifyEnvironmentConfig

> Provides the same functionality as the [modifyEnvironmentConfig](/plugins/dev/hooks.md#modifyenvironmentconfig) plugin API.

- **Version:** Added in v1.5.0
- **Example:**

```ts
rsbuild.modifyEnvironmentConfig((config, { name }) => {
  if (name !== 'web') {
    return config;
  }
  config.html.title = 'My Default Title';
});
```
