Plugin development
Rsbuild's architecture is centered on a plugin system. Most of Rsbuild's functionality is implemented through plugins, which keeps the core lightweight while providing flexible extensibility.
Rsbuild plugins are functions that can register hooks at different stages, listen to events, and execute custom logic. If you want to modify the default behavior, add new features, or integrate third-party tools, plugins provide a comprehensive API to fulfill these requirements.
Comparison
Before developing a Rsbuild plugin, you may have been familiar with the plugin systems of tools such as webpack, Vite, esbuild, etc.
Rsbuild's plugin API is similar to esbuild's, and compared with webpack or Rspack plugins, Rsbuild's plugin API is simpler and easier to get started with.
From a functional perspective, Rsbuild's plugin API mainly revolves around Rsbuild's operation process and build configuration, providing various hooks for extension. On the other hand, Rspack's plugin API is more complex and comprehensive, capable of modifying every aspect of the bundling process.
Rspack plugins can be integrated into Rsbuild plugins. If the hooks provided by Rsbuild do not meet your requirements, you can also implement the functionality using Rspack plugin and register Rspack plugins in the Rsbuild plugin:
Developing plugins
Plugins provide a function similar to (options?: PluginOptions) => RsbuildPlugin as an entry point.
Plugin example
Registering the plugin:
Plugin structure
Function-based plugins can accept an options object and return a plugin instance, managing internal state through closures.
The roles of each part are as follows:
- The
nameproperty is used to label the plugin's name. setupserves as the main entry point for the plugin logic.- The
apiobject contains various hooks and utility functions.
Naming convention
The naming convention for plugins is as follows:
- The function of the plugin is named
pluginAbcand exported by name. - The
nameof the plugin follows the formatscope:foo-barorplugin-foo-bar, addingscope:can avoid naming conflicts with other plugins.
Here is an example:
The name of official Rsbuild plugins uniformly uses rsbuild: as a prefix, for example, rsbuild:react corresponds to @rsbuild/plugin-react.
Template repository
rsbuild-plugin-template is a minimal Rsbuild plugin template repository that you can use as a basis for developing your Rsbuild plugin.
Environment plugin
Rsbuild supports building outputs for multiple environments at the same time, and supports add plugins for specified environment.
If you want the plugin you develop to support use as an Environment plugin, you need to pay attention to the following points:
- Each environment has its own Rsbuild config:
- Use environment context instead of
getRsbuildConfigto get environment information. - When modifying the Rsbuild config for a specific environment, prioritize using modifyEnvironmentConfig instead of modifyRsbuildConfig to avoid affecting other environments.
- Use environment context instead of
- Be aware of side effects, your plugin code may be executed multiple times:
- When the same plugin is registered multiple times in different environments, it will be regarded as multiple Rsbuild plugins (even if they point to the same plugin instance), because they have different Rsbuild environment contexts.
Here is an example:
Reference other plugins
Rsbuild's plugins config supports passing a nested array, which means you can reference and register other Rsbuild plugins within your plugin.
For example, register pluginBar within pluginFoo:
Lifetime hooks
Rsbuild internally uses lifecycle hooks to schedule tasks, and plugins can also register hooks to take part in any stage of the workflow and implement their own features.
The full list of Rsbuild's lifetime hooks can be found in the API References.
Rsbuild does not take over the hooks of the underlying Rspack, whose documents can be found here: Rspack Plugin API.
Migrate Vite plugin
See Migrate Vite plugin to learn how to migrate a Vite plugin to Rsbuild plugin.
Read and modify Rsbuild config
When a plugin needs to read or modify the project's Rsbuild config, use Rsbuild's config APIs.
Modify the base config
Register api.modifyRsbuildConfig during setup to modify the base config before it is merged with each environment's config:
modifyRsbuildConfig is a global hook. If a change applies only to certain environments or depends on the current environment, use api.modifyEnvironmentConfig instead. See Global hooks vs environment hooks for details.
Read the normalized config
After the config modification hooks have run, call api.getNormalizedConfig without arguments to get the complete normalized config for all environments. It includes default values, so its type is narrower than the value returned by api.getRsbuildConfig.
If no environment context is available but you need the config for one environment, pass its name to getNormalizedConfig:
See NormalizedConfig and NormalizedEnvironmentConfig for their return types.
Read the current environment config
When a hook callback includes an environment context, prefer environment.config. It is the normalized result of merging the base config with the current environment's config.
Read all environment configs
Global hooks such as onBeforeBuild and onAfterBuild receive environments, which contains the context for every environment. Iterate over it when a plugin needs to read each environment's config:
See Multi-environment builds for more details about environment configs.
Modify Rspack configuration
Rsbuild plugin allows you to modify the built-in Rspack configuration, including:
- api.modifyRspackConfig: Modify the Rspack configuration object.
- api.modifyBundlerChain: Modify the Rspack configuration through rspack-chain.
Example
For example, register eslint-rspack-plugin via Rsbuild plugin:
Extending plugin API
When building custom tools on top of Rsbuild's JavaScript API, you may want to extend the existing plugin API to provide additional capabilities — for example, exposing utility functions or sharing context objects.
You can achieve this by using the rsbuild.expose() method on the Rsbuild instance.
This method works the same way as the plugin's api.expose(), allowing you to expose custom methods or objects to Rsbuild plugins.
For example, you can expose getState and setCount methods:
Plugins can then access these extended APIs using the api.useExposed() method:
Dependency declaration
When publishing an Rsbuild plugin, you should declare @rsbuild/core in peerDependencies in package.json, and install it in devDependencies for local development:
If your plugin only references types from @rsbuild/core, you can declare it as an optional peer dependency:
In this case, the plugin will not produce unnecessary peer dependency warnings when it is used by higher-level tools based on Rsbuild, such as Rslib or Rspress.

