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

# Handle third-party dependencies

This section introduces how to handle third-party dependencies in bundle mode.

Generally, third-party dependencies required by a project can be installed via the `install` command in the package manager. After the third-party dependencies are successfully installed, they will generally appear under `dependencies` and `devDependencies` in the project `package.json`.

```json title="package.json"
{
  "dependencies": {},
  "devDependencies": {}
}
```

Dependencies under `"dependencies"` are generally required for the package in runtime, and if these third-party dependencies are declared under `"devDependencies"`, then there will be missing dependencies in production runtime.

In addition to `"dependencies"`, `"peerDependencies"`can also declare dependencies that are needed in the production environment, but it puts more emphasis on the existence of these dependencies declared by `"peerDependencies"` in the project's runtime environment, similar to the plugin mechanism.

## Default handling of third-party dependencies

By default, when generating CJS or ESM outputs, third-party dependencies under `"dependencies"`, `"optionalDependencies"` and `"peerDependencies"` are not bundled by Rslib.

This is because when the npm package is installed, its `"dependencies"` will also be installed. By not packaging `"dependencies"`, you can reduce the size of the package product.

If you need to package some dependencies, it is recommended to move them from `"dependencies"` to `"devDependencies"`, which is equivalent to prebundle the dependencies and reduces the size of the dependency installation.

The following example assumes that the project depends on `foo`:

```json title="package.json"
{
  "dependencies": {
    "foo": "^1.0.0"
  },
  // or
  "peerDependencies": {
    "foo": "^1.0.0"
  }
}
```

When the `foo` dependency is used in the source code:

```tsx title="src/index.ts"
import foo from 'foo';
console.info(foo);
```

The `foo` package will not be bundled into the output:

```js title="dist/index.js"
import foo from 'foo';
console.info(foo);
```

If you want to modify the default processing, you can use the following API:

- [output.autoExternal](/config/rsbuild/output.md#outputautoexternal)
- [output.externals](/config/rsbuild/output.md#outputexternals)

## Customize third-party dependency handling

Rslib mainly uses [output.autoExternal](/config/rsbuild/output.md#outputautoexternal) and [output.externals](/config/rsbuild/output.md#outputexternals) to control whether third-party dependencies are bundled.

### Configure autoExternal

To override the behavior of `output.autoExternal` described above and bundle these dependencies, set it to `false`:

```ts title="rslib.config.ts"
export default defineConfig({
  lib: [
    {
      output: {
        autoExternal: false,
      },
    },
  ],
});
```

If you only want to adjust certain dependency types, use the object form:

```ts title="rslib.config.ts"
export default defineConfig({
  lib: [
    {
      output: {
        autoExternal: {
          dependencies: true,
          optionalDependencies: true,
          peerDependencies: true,
          devDependencies: false,
        },
      },
    },
  ],
});
```

Use [exclude](https://rsbuild.rs/config/output/auto-external#exclude) to exclude specific packages from the external rules auto-generated by `output.autoExternal`. If a package is excluded, its subpath imports will not be externalized either:

```ts title="rslib.config.ts"
export default defineConfig({
  lib: [
    {
      output: {
        autoExternal: {
          exclude: ['react', /^@scope\//],
        },
      },
    },
  ],
});
```

### Configure externals

Use [output.externals](/config/rsbuild/output.md#outputexternals) when you need to specify modules that should not be bundled by Rslib, or when you need to change the request path after externalization.

The array form is useful when you want to keep the original request paths:

```ts title="rslib.config.ts"
export default defineConfig({
  lib: [
    {
      output: {
        externals: ['react', 'react/jsx-runtime'],
      },
    },
  ],
});
```

The object form can specify the request path after externalization, commonly used to rename externalized modules:

```ts title="rslib.config.ts"
export default defineConfig({
  lib: [
    {
      output: {
        externals: {
          react: 'react-18',
          'react/jsx-runtime': 'react-18/jsx-runtime',
        },
      },
    },
  ],
});
```

:::tip
Subpath imports such as `react/jsx-runtime` need to be handled separately. Configuring only `react` does not mean `react/jsx-runtime` will use the same external rule.
:::

If you want to match a group of modules, use a regular expression:

```ts title="rslib.config.ts"
export default defineConfig({
  lib: [
    {
      output: {
        externals: [/^react($|\/)/],
      },
    },
  ],
});
```

For complex scenarios where you need to decide whether to externalize a module based on the request issuer or context, configure Rspack's `externals` via [tools.rspack](/config/rsbuild/tools.md#toolsrspack):

```ts title="rslib.config.ts"
export default defineConfig({
  lib: [
    {
      tools: {
        rspack: {
          externals: [
            ({ request }, callback) => {
              if (request?.startsWith('react')) {
                callback(null, request);
                return;
              }

              callback();
            },
          ],
        },
      },
    },
  ],
});
```

For more details, see the Rspack [Externals](https://rspack.rs/config/externals) documentation.

## Bundle dependencies loaded via `createRequire()`

The Node.js ES module environment does not provide the CommonJS `require` function. If you need to use CommonJS loading semantics in an ES module, you can create a `require` function with Node.js [`createRequire()`](https://nodejs.org/api/module.html#modulecreaterequirefilename):

```ts title="src/index.ts"
import { createRequire } from 'node:module';

const require = createRequire(import.meta.url);
const foo = require('foo');

export const bar = foo.bar;
```

Rslib keeps `createRequire()` calls in the output by default. To let Rspack analyze the `require()` calls created by it and bundle dependencies loaded by statically analyzable calls such as `require('foo')`, enable [`module.parser.javascript.createRequire`](https://rspack.rs/config/module-parser#javascriptcreaterequire).

```ts title="rslib.config.ts"
import { defineConfig } from '@rslib/core';

export default defineConfig({
  tools: {
    rspack: {
      module: {
        parser: {
          javascript: {
            createRequire: true,
          },
        },
      },
    },
  },
});
```

If bundled dependencies contain `createRequire()` calls that need to be kept at runtime, use `module.rules` to enable this capability only for JavaScript/TypeScript modules outside `node_modules`:

```ts title="rslib.config.ts"
import { defineConfig } from '@rslib/core';

export default defineConfig({
  tools: {
    rspack: {
      module: {
        rules: [
          {
            test: /\.[cm]?[jt]sx?$/,
            exclude: /node_modules/,
            parser: {
              createRequire: true,
            },
          },
        ],
      },
    },
  },
});
```
