close
  • English
  • React

    In this document, you will learn how to build a React component library with Rslib. You can check out React related example projects in Examples.

    Create React project

    You can use create-rslib to create a project with Rslib + React. Just execute the following command:

    npm
    yarn
    pnpm
    bun
    npm create rslib@latest

    Then select React when prompted to "Select template".

    Use Rslib in an existing project

    To develop a React library, you need to set the target to "web" in rslib.config.ts. This is crucial because Rslib sets the target to "node" by default, which differs from the default target of Rsbuild.

    To compile React (JSX and TSX), you need to register the Rsbuild React Plugin. The plugin will automatically add the necessary configuration for React builds.

    For example, register in rslib.config.ts:

    rslib.config.ts
    import { 
    function defineConfig(config: RslibConfig): RslibConfig (+3 overloads)

    This function helps you to autocomplete configuration types. It accepts a Rslib config object, or a function that returns a config.

    defineConfig
    } from '@rslib/core';
    import {
    const pluginReact: (options?: PluginReactOptions) => RsbuildPlugin
    pluginReact
    } from '@rsbuild/plugin-react';
    export default
    function defineConfig(config: RslibConfig): RslibConfig (+3 overloads)

    This function helps you to autocomplete configuration types. It accepts a Rslib config object, or a function that returns a config.

    defineConfig
    ({
    RslibConfig.lib: LibConfig[]
    lib
    : [
    // ... ],
    RslibConfig.output?: RslibOutputConfig | undefined

    Options for build outputs.

    @inheritdoc
    output
    : {
    RslibOutputConfig.target?: RsbuildTarget | undefined

    Setting the build target for Rsbuild.

    @override@default'node'
    target
    : 'web',
    },
    EnvironmentConfig.plugins?: RsbuildPlugins | undefined

    Configure Rsbuild plugins.

    plugins
    : [
    function pluginReact(options?: PluginReactOptions): RsbuildPlugin
    pluginReact
    (/** options here */)],
    });

    JSX transform

    • Type: 'automatic' | 'classic' | 'preserve'
    • Default: 'automatic'

    React introduced a new JSX transform in version 17. This new transform removes the need to import React when using JSX.

    By default, Rslib uses the new JSX transform, which is runtime: 'automatic'. It requires at least React 16.14.0 or higher and the peerDependencies should be specified as "react": ">=16.14.0".

    To change the JSX transform, you can set the swcReactOptions option in @rsbuild/plugin-react.

    For example, to use the classic runtime:

    rslib.config.ts
    import { 
    const pluginReact: (options?: PluginReactOptions) => RsbuildPlugin
    pluginReact
    } from '@rsbuild/plugin-react';
    import {
    function defineConfig(config: RslibConfig): RslibConfig (+3 overloads)

    This function helps you to autocomplete configuration types. It accepts a Rslib config object, or a function that returns a config.

    defineConfig
    } from '@rslib/core';
    export default
    function defineConfig(config: RslibConfig): RslibConfig (+3 overloads)

    This function helps you to autocomplete configuration types. It accepts a Rslib config object, or a function that returns a config.

    defineConfig
    ({
    RslibConfig.lib: LibConfig[]
    lib
    : [
    // ... ],
    RslibConfig.output?: RslibOutputConfig | undefined

    Options for build outputs.

    @inheritdoc
    output
    : {
    RslibOutputConfig.target?: RsbuildTarget | undefined

    Setting the build target for Rsbuild.

    @override@default'node'
    target
    : 'web',
    },
    EnvironmentConfig.plugins?: RsbuildPlugins | undefined

    Configure Rsbuild plugins.

    plugins
    : [
    function pluginReact(options?: PluginReactOptions): RsbuildPlugin
    pluginReact
    ({
    swcReactOptions?: ReactConfig | undefined

    Configure the behavior of SWC to transform React code, the same as SWC's jsc.transform.react.

    swcReactOptions
    : {
    ReactConfig.runtime?: "automatic" | "classic" | "preserve" | undefined

    Decides which runtime to use when transforming JSX.

    • "automatic" - Automatically imports the functions that JSX transpiles to. This is the modern approach introduced in React 17+ that eliminates the need to manually import React in every file that uses JSX.
    • "classic" - Uses the traditional JSX transform that relies on React.createElement calls. Requires React to be in scope, which was the standard behavior before React 17.
    • "preserve" - Leaves JSX syntax unchanged without transforming it.
    @default"classic"
    runtime
    : 'classic',
    }, }), ], });

    When you need to keep native JSX in the build output, you can set the runtime to 'preserve' to leave JSX syntax unchanged without transforming it, which is useful for subsequent processing by other bundlers.

    Warning

    When using runtime: 'preserve', you must set bundle: false to enable bundleless mode to keep files unbundled.

    To emit .jsx files, you can configure the JS filename template through output.filename option:

    rslib.config.ts
    import { 
    const pluginReact: (options?: PluginReactOptions) => RsbuildPlugin
    pluginReact
    } from '@rsbuild/plugin-react';
    import {
    function defineConfig(config: RslibConfig): RslibConfig (+3 overloads)

    This function helps you to autocomplete configuration types. It accepts a Rslib config object, or a function that returns a config.

    defineConfig
    } from '@rslib/core';
    export default
    function defineConfig(config: RslibConfig): RslibConfig (+3 overloads)

    This function helps you to autocomplete configuration types. It accepts a Rslib config object, or a function that returns a config.

    defineConfig
    ({
    RslibConfig.lib: LibConfig[]
    lib
    : [
    {
    LibConfig.bundle?: boolean | undefined

    Whether to bundle the library.

    @defaultValuetrue@seehttps://rslib.rs/config/lib/bundle
    bundle
    : false,
    LibConfig.format?: Format | undefined

    Output format for the generated JavaScript files.

    @defaultValue'esm'@seehttps://rslib.rs/config/lib/format
    format
    : 'esm',
    LibConfig.output?: RslibOutputConfig | undefined

    Options for build outputs.

    @inheritdoc
    output
    : {
    OutputConfig.filename?: FilenameConfig | undefined

    Sets the filename of output files.

    filename
    : {
    js?: Filename | undefined

    The name of the JavaScript files.

    @default

    - dev: '[name].js'

    • prod: '[name].[contenthash:10].js'
    js
    : '[name].jsx',
    }, }, }, ],
    EnvironmentConfig.plugins?: RsbuildPlugins | undefined

    Configure Rsbuild plugins.

    plugins
    : [
    function pluginReact(options?: PluginReactOptions): RsbuildPlugin
    pluginReact
    ({
    swcReactOptions?: ReactConfig | undefined

    Configure the behavior of SWC to transform React code, the same as SWC's jsc.transform.react.

    swcReactOptions
    : {
    ReactConfig.runtime?: "automatic" | "classic" | "preserve" | undefined

    Decides which runtime to use when transforming JSX.

    • "automatic" - Automatically imports the functions that JSX transpiles to. This is the modern approach introduced in React 17+ that eliminates the need to manually import React in every file that uses JSX.
    • "classic" - Uses the traditional JSX transform that relies on React.createElement calls. Requires React to be in scope, which was the standard behavior before React 17.
    • "preserve" - Leaves JSX syntax unchanged without transforming it.
    @default"classic"
    runtime
    : 'preserve',
    }, }), ], });

    JSX import source

    • Type: string
    • Default: 'react'

    When runtime is set to 'automatic', you can specify the import path of the JSX transform through importSource.

    For example, when using Emotion, you can set importSource to '@emotion/react':

    rslib.config.ts
    import { 
    const pluginReact: (options?: PluginReactOptions) => RsbuildPlugin
    pluginReact
    } from '@rsbuild/plugin-react';
    import {
    function defineConfig(config: RslibConfig): RslibConfig (+3 overloads)

    This function helps you to autocomplete configuration types. It accepts a Rslib config object, or a function that returns a config.

    defineConfig
    } from '@rslib/core';
    export default
    function defineConfig(config: RslibConfig): RslibConfig (+3 overloads)

    This function helps you to autocomplete configuration types. It accepts a Rslib config object, or a function that returns a config.

    defineConfig
    ({
    RslibConfig.lib: LibConfig[]
    lib
    : [
    // ... ],
    RslibConfig.output?: RslibOutputConfig | undefined

    Options for build outputs.

    @inheritdoc
    output
    : {
    RslibOutputConfig.target?: RsbuildTarget | undefined

    Setting the build target for Rsbuild.

    @override@default'node'
    target
    : 'web',
    },
    EnvironmentConfig.plugins?: RsbuildPlugins | undefined

    Configure Rsbuild plugins.

    plugins
    : [
    function pluginReact(options?: PluginReactOptions): RsbuildPlugin
    pluginReact
    ({
    swcReactOptions?: ReactConfig | undefined

    Configure the behavior of SWC to transform React code, the same as SWC's jsc.transform.react.

    swcReactOptions
    : {
    ReactConfig.importSource?: string | undefined

    Declares the module specifier to be used for importing the jsx and jsxs factory functions when using runtime 'automatic'

    @default"react"
    importSource
    : '@emotion/react',
    }, }), ], });

    React Compiler

    React Compiler is a build-time tool that automatically optimizes your React app. It works with plain JavaScript, and understands the Rules of React, so you don't need to rewrite any code to use it.

    Before using React Compiler, we recommend reading the React Compiler documentation to understand its functionality, current state, and usage.

    How to use

    Steps to use React Compiler in Rslib:

    1. Upgrade react and react-dom to v19. If you can't upgrade, install the react-compiler-runtime package to run the compiled code on earlier versions.
    2. React Compiler currently only provides a Babel plugin. Install @rsbuild/plugin-babel and babel-plugin-react-compiler.
    3. Register the Babel plugin in your Rslib config file:
    rslib.config.ts
    import { pluginBabel } from '@rsbuild/plugin-babel';
    import { pluginReact } from '@rsbuild/plugin-react';
    import { defineConfig } from '@rslib/core';
    
    export default defineConfig({
      plugins: [
        pluginReact(),
        pluginBabel({
          include: /\.[jt]sx?$/,
          exclude: [/[\\/]node_modules[\\/]/],
          babelLoaderOptions(opts) {
            opts.plugins ??= [];
            opts.plugins.unshift('babel-plugin-react-compiler');
          },
        }),
      ],
    });
    Tip

    The include pattern uses /\.[jt]sx?$/ to match .js, .jsx, .ts, and .tsx files. This ensures React Compiler can optimize both components and custom hooks, which are often defined in plain .ts files. The exclude for node_modules prevents the compiler from processing third-party dependencies.

    If you only want to compile JSX/TSX files, you can use include: /\.(?:jsx|tsx)$/ instead, but custom hooks in .ts files will not be optimized.

    You can also refer to the example project.

    Configuration

    Set the config for React Compiler as follows:

    rslib.config.ts
    import { pluginBabel } from '@rsbuild/plugin-babel';
    import { pluginReact } from '@rsbuild/plugin-react';
    import { defineConfig } from '@rslib/core';
    
    const ReactCompilerConfig = {
      /* ... */
    };
    
    export default defineConfig({
      plugins: [
        pluginReact(),
        pluginBabel({
          include: /\.[jt]sx?$/,
          exclude: [/[\\/]node_modules[\\/]/],
          babelLoaderOptions(opts) {
            opts.plugins ??= [];
            opts.plugins.unshift([
              'babel-plugin-react-compiler',
              ReactCompilerConfig,
            ]);
          },
        }),
      ],
    });

    For React 17 and 18 projects, install react-compiler-runtime and specify the target:

    rslib.config.ts
    const ReactCompilerConfig = {
      target: '18', // '17' | '18' | '19'
    };

    SVGR

    Read SVGR for more details.

    Further reading