--- url: /guide/start/index.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Introduction Rslib is a library development tool based on [Rsbuild](https://rsbuild.rs). It gives developers a simple way to create JavaScript libraries and UI component libraries, and provides tool integrations and best practices for building, debugging, documentation, and testing throughout library development. ## Why Rslib During the development of component or utility libraries, developers need to focus not only on implementing project logic, but also on handling tasks that are separate from the code itself, such as building, debugging, documentation, and testing. Although many community tools and solutions can address some of these needs, developers who are not familiar with them often face cumbersome configuration requirements or need to coordinate multiple tools to meet these demands. Based on Rspack and Rsbuild, Rslib offers a comprehensive solution tailored to the diverse requirements of library development, effectively addressing issues such as incomplete tool ecosystems, high costs for module standard compatibility, and insufficient output optimization. Rslib optimizes webpack's limited support for library ESM outputs, reducing redundant runtime code and generating high-quality ESM outputs that are tree-shaking friendly for library consumers. Additionally, Rslib fully leverages the build performance advantages of Rspack and capitalizes the strengths of both the webpack and Rspack ecosystems to robustly support features such as Module Federation. Furthermore, Rslib utilizes Rsbuild's out-of-the-box configuration to facilitate configuration sharing between application and library projects, resolving the challenge of reusing build configurations between application projects and library projects, thereby reducing the configuration overhead for developers and improving development efficiency and experience. In the future, Rslib will explore additional possibilities by leveraging the new features of Rspack. ## Features Rslib has the following features: - **Easy to configure**: Out-of-the-box tooling enables developers to build libraries with zero configuration. Rslib also provides a set of semantic build configurations that can be extended as project needs grow. - **Performance-focused**: Powered by [Rspack](https://rspack.rs), it integrates high-performance Rust-based tools from the community, including [SWC](https://swc.rs/) and [Lightning CSS](https://lightningcss.dev/), delivering first-class build speed and development experience. - **Plugin ecosystem**: Supports [Rsbuild plugins](https://rsbuild.rs/plugins/list/), Rspack plugins, and webpack plugins, allowing developers to reuse existing plugin ecosystems and continue using familiar development workflows and engineering practices. - **Flexible outputs**: Designed around the diverse ways libraries are published and consumed, it supports flexible build output configuration for different runtimes, distribution methods, and downstream build tools to meet the delivery needs of different types of libraries. - **Framework agnostic**: Decoupled from frontend UI frameworks, it supports React, Vue, Svelte, Solid, and other frameworks through plugins, allowing developers to build component libraries for different frameworks with a consistent configuration and development workflow. ## Rstack Rslib is part of Rstack, the fast, unified JavaScript toolchain for developers and agents. ![Rstack](https://assets.rspack.rs/rstack/rstack-overview.png) Rstack includes the following tools: | Name | Description | Version | | ----------------------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Rspack](https://github.com/web-infra-dev/rspack) | Bundler | npm version | | [Rsbuild](https://github.com/web-infra-dev/rsbuild) | Build tool | npm version | | [Rslib](https://github.com/web-infra-dev/rslib) | Library development tool | npm version | | [Rspress](https://github.com/web-infra-dev/rspress) | Static site generator | npm version | | [Rsdoctor](https://github.com/web-infra-dev/rsdoctor) | Build analyzer | npm version | | [Rstest](https://github.com/web-infra-dev/rstest) | Testing framework | npm version | | [Rslint](https://github.com/web-infra-dev/rslint) | Linter | npm version | ## Links - [awesome-rstack](https://github.com/rstackjs/awesome-rstack): A curated list of awesome things related to Rstack. - [agent-skills](https://github.com/rstackjs/agent-skills): A collection of Agent Skills for Rstack. - [rstack-examples](https://github.com/rstackjs/rstack-examples): Examples showcasing Rstack tools. - [storybook-rsbuild](https://github.com/rstackjs/storybook-rsbuild): Storybook builder powered by Rsbuild. - [rsbuild-plugin-template](https://github.com/rstackjs/rsbuild-plugin-template): Use this template to create your own Rsbuild plugin. - [rstack-design-resources](https://github.com/rstackjs/rstack-design-resources): Design resources for Rstack. ## Community Come and chat with us on [Discord](https://discord.gg/XsaKEEk4mW)! The Rstack team and users are active there, and we're always looking for contributions. ## Online example Try Rslib online with the [StackBlitz example](https://stackblitz.com/~/github.com/rstackjs/rslib-stackblitz-example). ## Next steps Please read [Quick start](/guide/start/quick-start.md) to start using Rslib. --- url: /guide/start/quick-start.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Quick start ## Environment preparation Rslib supports using [Node.js](https://nodejs.org/), [Deno](https://deno.com/), or [Bun](https://bun.sh/) as the JavaScript runtime. Use one of the following installation guides to set up a runtime: - [Install Node.js](https://nodejs.org/en/download) - [Install Bun](https://bun.com/docs/installation) - [Install Deno](https://docs.deno.com/runtime/getting_started/installation/) :::tip Version requirements Rslib v1 requires Node.js version 20.19+, 22.12+. ::: ## Creating an Rslib project Use [`create-rslib`](https://www.npmjs.com/package/create-rslib) to create a new Rslib project. Run the following command: ```sh [npm] npm create rslib@latest ``` ```sh [yarn] yarn create rslib ``` ```sh [pnpm] pnpm create rslib@latest ``` ```sh [bun] bun create rslib@latest ``` ```sh [deno] deno init --npm rslib@latest ``` Follow the prompts step by step. During project creation, you can choose a template, language, optional tools, and optional skills. All templates include [Rstest](https://rstest.rs/) by default for testing. By default, the scaffold initializes a Git repository in the generated project. Pass `--no-git` to skip Git initialization. After creating the project, do the following: - Run `npm install` (or your package manager's install command) to install dependencies. - Run `npm run dev` to start watch mode and begin development. ### Templates When creating a project, you can choose from the following templates provided by `create-rslib`: | Template | Description | | --------------- | ------------------------ | | Node.js package | Node.js package | | React | React component library | | Vue | Vue component library | | Svelte | Svelte component library | | Solid | Solid component library | ### Optional tools `create-rslib` can help you set up the following commonly used tools. Use the arrow keys to navigate and the space bar to select. Press Enter without selecting anything to skip these tools. | Tool | Use | | --------------------------------------------------------- | --------------------------------------------------------- | | [ESLint](https://eslint.org/) | Linting | | [Rslint](https://rslint.rs/) | Linting | | [Prettier](https://prettier.io/) | Formatting | | [Biome](https://biomejs.dev/) | Linting and formatting | | [Rspress](https://rspress.rs/) | Component documentation, React + TypeScript template | | [Storybook](https://storybook.js.org/) | Component development and preview, React or Vue templates | | [React Compiler](/guide/solution/react.md#react-compiler) | Optimizing React components, React template only | ### Optional skills `create-rslib` can install optional skills for coding agents that support Skills. In interactive mode, your selections in “Optional tools” affect the available skill options. The currently available skills are: | Name | Condition | | ------------------------------------------------------------------------------------------------------- | ---------------- | | [rslib-best-practices](https://github.com/rstackjs/agent-skills#rslib-best-practices) | Default | | [rstest-best-practices](https://github.com/rstackjs/agent-skills#rstest-best-practices) | Default | | [rspress-custom-theme](https://github.com/rstackjs/agent-skills#rspress-custom-theme) | Choose `Rspress` | | [rspress-description-generator](https://github.com/rstackjs/agent-skills#rspress-description-generator) | Choose `Rspress` | Use the arrow keys to navigate and the space bar to select. Press Enter without selecting anything to skip. ```text ◆ Select optional skills (Use to select, to continue) │ ◻ Rslib - best practices │ ◻ Rstest - best practices ``` For more details about Agent Skills and other AI-related capabilities, see [AI](/guide/start/ai.md). ### Current directory To create a project in the current directory, set the target folder to `.`: ```text ◆ Create Rslib Project │ ◇ Project name or path │ . │ ◇ "." is not empty, please choose: │ Continue and override files ``` ### Non-interactive mode [create-rslib](https://www.npmjs.com/package/create-rslib) supports a non-interactive mode via command-line options. This mode skips prompts and creates the project directly, which is useful for scripts, CI, and automation. For example, the following command creates a React project in the `my-project` directory: ```bash npx -y create-rslib@latest my-project --template react # Using abbreviations npx -y create-rslib@latest my-project -t react # Specify multiple tools npx -y create-rslib@latest my-project -t react --tools storybook,biome # Install an optional skill for coding agents npx -y create-rslib@latest my-project -t react --skill rslib-best-practices ``` All CLI flags supported by `create-rslib`: ```text Usage: create-rslib [dir] [options] Options: -h, --help display help for command -d, --dir create project in specified directory -t, --template specify the template to use --no-git skip Git repository initialization --tools add additional tools, comma separated --skill add optional skills, comma separated --override override files in target directory --packageName specify the package name Available templates: node-js, node-ts, react-js, react-ts, vue-js, vue-ts, svelte-js, svelte-ts, solid-js, solid-ts Optional tools: react-compiler, eslint, rslint, biome, prettier, rspress, storybook Optional skills: rslib-best-practices, rstest-best-practices, rspress-custom-theme, rspress-description-generator ``` ## Migrate from existing projects To migrate from an existing project to Rslib, refer to the following guides: - [Migrating from tsup](/guide/migration/tsup.md) - [Migrating from tsc](/guide/migration/tsc.md) ### Other projects For other types of projects, you can manually install the [@rslib/core](https://www.npmjs.com/package/@rslib/core) package: ```sh [npm] npm add @rslib/core -D ``` ```sh [yarn] yarn add @rslib/core -D ``` ```sh [pnpm] pnpm add @rslib/core -D ``` ```sh [bun] bun add @rslib/core -D ``` ```sh [deno] deno add npm:@rslib/core -D ``` Then refer to the guide and documentation to enable the features you need: - See [CLI](/guide/basic/cli.md) to learn about available CLI commands. - See [Configure Rslib](/guide/basic/configure-rslib.md) to configure Rslib. --- url: /guide/start/glossary.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Glossary ## ESM ESM stands for [ECMAScript modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules), which is a modern module system introduced in ES2015 that allows JavaScript code to be organized into reusable, self-contained modules. ESM is now the standard for both [browser](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and [Node.js](https://nodejs.org/api/esm.html) environments, replacing older module systems like [CommonJS (CJS)](https://nodejs.org/api/modules.html) and [AMD](https://requirejs.org/docs/whyamd.html). ## CJS CJS stands for [CommonJS modules](https://nodejs.org/api/modules.html#modules-commonjs-modules), which is a module system used in JavaScript, particularly in server-side environments like Node.js. It was created to allow JavaScript to be used outside of the browser by providing a way to manage modules and dependencies. ## UMD UMD stands for [Universal Module Definition](https://github.com/umdjs/umd), a pattern for writing JavaScript modules that can work universally across different environments, such as both the browser and Node.js. Its primary goal is to ensure compatibility with the most popular module systems, including AMD (Asynchronous Module Definition), CommonJS (CJS), and browser globals. ## Bundleless Bundleless means that each source file is compiled and built separately, but not bundled together. Each output file can be found with its corresponding source code file. The process of bundleless build can also be understood as the process of code transformation of source files only. ## Module Federation Module Federation is an architectural pattern for JavaScript application decomposition (similar to microservices on the server-side), allowing you to share code and resources between multiple JavaScript applications (or micro-frontends). See [Module Federation](https://rsbuild.rs/guide/advanced/module-federation) for more details. ## More See more glossary in [Rsbuild - Glossary](https://rsbuild.rs/guide/start/glossary) and [Rspack - Glossary](https://rspack.rs/misc/glossary). --- url: /guide/start/npm-packages.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Packages This document showcases all the npm package information maintained by Rslib team. ## @rslib/core ![](https://img.shields.io/npm/v/@rslib/core?style=flat-square\&colorA=564341\&colorB=F8F5FF) Rslib core package that provides CLI commands and build capabilities based on Rsbuild. - [npm](https://npmjs.com/package/@rslib/core) - [Source Code](https://github.com/web-infra-dev/rslib/tree/main/packages/core) ## rsbuild-plugin-dts ![](https://img.shields.io/npm/v/rsbuild-plugin-dts?style=flat-square\&colorA=564341\&colorB=F8F5FF) Rsbuild plugin that supports emitting declaration files for TypeScript. - [npm](https://npmjs.com/package/rsbuild-plugin-dts) - [Source Code](https://github.com/web-infra-dev/rslib/tree/main/packages/plugin-dts) ## create-rslib ![](https://img.shields.io/npm/v/create-rslib?style=flat-square\&colorA=564341\&colorB=F8F5FF) Used to create a new Rslib project. - [npm](https://npmjs.com/package/create-rslib) - [Source Code](https://github.com/web-infra-dev/rslib/tree/main/packages/create-rslib) --- url: /guide/start/ai.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # AI To help AI better understand Rslib's features, configuration, and best practices so it can provide more accurate assistance during day-to-day development and troubleshooting, Rslib provides the following capabilities: - [Agent Skills](#agent-skills) - [llms.txt](#llmstxt) - [Markdown docs](#markdown-docs) - [AGENTS.md](#agentsmd) ## Agent Skills Agent Skills are domain-specific knowledge packs that can be installed into Agents, enabling them to give more accurate and professional suggestions or perform actions in specific scenarios. In the [rstackjs/agent-skills](https://github.com/rstackjs/agent-skills) repository, there are many skills for the Rstack ecosystem. The skills related to Rslib include: - [rslib-best-practices](https://github.com/rstackjs/agent-skills#rslib-best-practices): Best practices for Rslib. - [rslib-modern-package](https://github.com/rstackjs/agent-skills#rslib-modern-package): Recommendations for designing and publishing modern JavaScript packages. - [migrate-to-rslib](https://github.com/rstackjs/agent-skills#migrate-to-rslib): Migrate existing tsc or tsup projects to Rslib. In Coding Agents that support skills, you can use the [skills](https://www.npmjs.com/package/skills) package to install a specific skill with the following command: ```sh [npx] npx skills add rstackjs/agent-skills --skill migrate-to-rslib ``` ```sh [yarn] yarn dlx skills add rstackjs/agent-skills --skill migrate-to-rslib ``` ```sh [pnpm] pnpm dlx skills add rstackjs/agent-skills --skill migrate-to-rslib ``` ```sh [bunx] bunx skills add rstackjs/agent-skills --skill migrate-to-rslib ``` ```sh [deno] deno run -A npm:skills add rstackjs/agent-skills --skill migrate-to-rslib ``` After installation, simply use natural language prompts to trigger the skill, for example: ``` Help me migrate this tsc project to Rslib ``` ## llms.txt [llms.txt](https://llmstxt.org/) is a standard that helps LLMs discover and use project documentation. Rslib follows this standard and publishes the following two files: - [llms.txt](https://rslib.rs/llms.txt): A structured index file containing the titles, links, and brief descriptions of all documentation pages. ``` https://rslib.rs/llms.txt ``` - [llms-full.txt](https://rslib.rs/llms-full.txt): A full-content file that concatenates the complete content of every documentation page into a single file. ``` https://rslib.rs/llms-full.txt ``` You can choose the file that best fits your use case: - `llms.txt` is smaller and consumes fewer tokens, making it suitable for AI to fetch specific pages on demand. - `llms-full.txt` contains the complete documentation content, so AI doesn't need to follow individual links — ideal when you need AI to have a comprehensive understanding of Rslib, though it consumes more tokens and is best used with AI tools that support large context windows. ## Markdown docs Every Rslib documentation page has a corresponding `.md` plain-text version that can be provided directly to AI. On any doc page, you can click “Copy Markdown” or “Copy Markdown Link” in the page outline to get the Markdown content or link. ``` https://rslib.rs/guide/start/index.md ``` Providing the Markdown link or content allows AI to focus on a specific chapter, which is useful for targeted troubleshooting or looking up a particular topic. ## AGENTS.md When you create a new project with [create-rslib](https://www.npmjs.com/package/create-rslib), the generated project includes an `AGENTS.md` file. This file follows the [AGENTS.md](https://agents.md/) specification and provides key project information to Agents. Example `AGENTS.md` content: ```markdown wrapCode # AGENTS.md You are an expert in JavaScript, Rspack, Rsbuild, Rslib, and library development. You write maintainable, performant, and accessible code. ## Commands - `npm run build` - Build the library for production - `npm run dev` - Turn on watch mode, watch for changes and rebuild the library ## Docs - Rslib: https://rslib.rs/llms.txt - Rsbuild: https://rsbuild.rs/llms.txt - Rspack: https://rspack.rs/llms.txt ``` You can also customize it for your project, adding more details about the project structure, overall architecture, and other relevant information so Agents can better understand your project. --- url: /guide/solution/index.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Overview In this chapter, we will introduce how to use Rslib to development libraries for browser and Node.js. We will also cover how to create libraries for different UI frameworks. ## Browser target When developing a library that runs in the browser, you can package it in both [ESM](/guide/basic/output-format.md#esm--cjs) and [CJS](/guide/basic/output-format.md#esm--cjs) formats for integration with application bundlers. Configuring the package [conditional exports](https://nodejs.org/api/packages.html#conditional-exports) to ESM output allows for better tree shaking. Additionally, you can create [UMD](/guide/basic/output-format.md#umd) format output for direct browser use and even generate [Module Federation ](/guide/advanced/module-federation.md) formats for dynamic loading by other applications. Configure [Browserslist](https://rsbuild.rs/guide/advanced/browserslist) according to the target browser support to determine the downgrade syntax of the output, or add a [polyfill](/guide/advanced/output-compatibility.md) for API compatibility. When publishing to npm, you can choose not to [minify](/config/rsbuild/output.md#outputminify) your code or to minify it while providing a [sourcemap](/config/rsbuild/output.md#outputsourcemap) to enhance the debugging experience for users of your library. For styling, you can use CSS, or CSS pre-processors like Sass, Less, or Stylus, or apply PostCSS for CSS post-processing. Tools like Tailwind CSS can also help in building your styles. Using CSS Modules to create CSS modules is another option. In terms of resource management, Rslib handles static assets used in your code, such as SVG and PNG files, and supports compiling [Web Workers](/guide/advanced/web-workers.md) for ESM libraries. You can also build a component library of [React](/guide/solution/react.md), [Preact](https://github.com/rstackjs/rstack-examples/tree/main/rslib/preact), or other frameworks, and use [Storybook](/guide/advanced/storybook.md) for UI component development and testing. Refer to the solutions in this chapter to learn how to use Rslib to develop browser libraries for different frameworks. ## Node.js target Rslib set [target](/config/rsbuild/output.md#outputtarget) to `"node"` by default to development libraries for Node.js. You can create a [pure ESM](/guide/basic/output-format.md#esm--cjs) package or a [dual package](/guide/basic/output-format.md#esm--cjs) that supports both ESM and CJS as needed. In CJS output, `import.meta.url` will be automatically [shimmed](/config/lib/shims.md) for compatibility and `__dirname` and `__filename` got optional ESM shims to ensure proper use across different module system. Node.js's built-in packages will be [externalized by default](/guide/advanced/third-party-deps.md). --- url: /guide/solution/nodejs.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Node.js In this document, you will learn how to build a Node.js library using Rslib. You can check out Node.js related example projects in [Examples](https://github.com/rstackjs/rstack-examples/tree/main/rslib). ## Create Node.js project You can use `create-rslib` to create a project with Rslib + Node.js. Just execute the following command: ```sh [npm] npm create rslib@latest ``` ```sh [yarn] yarn create rslib ``` ```sh [pnpm] pnpm create rslib@latest ``` ```sh [bun] bun create rslib@latest ``` Then select `Node.js` when prompted to "Select template". ## Use Rslib in an existing project Rslib offers seamless support for Node.js projects, allowing you to build them effortlessly with minimal configuration. For example, in `rslib.config.ts`: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({}); ``` ## Target for Node.js Rslib sets [target](/config/rsbuild/output.md#outputtarget) to `"node"` by default, which is different from the default target of Rsbuild. When target is set to `"node"`, Rslib adjusts many configurations for Node.js. For example, [output.externals](/config/rsbuild/output.md#outputtarget) will exclude built-in Node.js modules, and [shims](/config/lib/shims.md) will add a shim for `import.meta.url` in CJS output by default. ### Externals All Node.js [built-in modules](https://nodejs.org/docs/latest/api/) are externalized by default. ### Shims - `global`: leave it as it is, while it's recommended to use [globalThis](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) instead. - `__filename`: When outputting in ESM format, replace `__filename` with the result of `fileURLToPath(import.meta.url)`. - `__dirname`: When outputting in ESM format, replace `__dirname` with the result of `dirname(fileURLToPath(import.meta.url))`. --- url: /guide/solution/react.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # 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](https://github.com/rstackjs/rstack-examples/tree/main/rslib). ## Create React project You can use `create-rslib` to create a project with Rslib + React. Just execute the following command: ```sh [npm] npm create rslib@latest ``` ```sh [yarn] yarn create rslib ``` ```sh [pnpm] pnpm create rslib@latest ``` ```sh [bun] bun 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](/config/rsbuild/output.md#outputtarget) 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](https://rsbuild.rs/plugins/list/plugin-react). The plugin will automatically add the necessary configuration for React builds. For example, register in `rslib.config.ts`: ```ts title="rslib.config.ts" twoslash import { defineConfig } from '@rslib/core'; import { pluginReact } from '@rsbuild/plugin-react'; // [!code highlight] export default defineConfig({ lib: [ // ... ], // [!code highlight:4] output: { target: 'web', }, plugins: [pluginReact(/** options here */)], }); ``` ## JSX transform - **Type:** `'automatic' | 'classic' | 'preserve'` - **Default:** `'automatic'` React introduced a [new JSX transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) 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](https://rsbuild.rs/plugins/list/plugin-react#swcreactoptionsruntime) option in `@rsbuild/plugin-react`. For example, to use the classic runtime: ```ts title="rslib.config.ts" twoslash import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ // ... ], output: { target: 'web', }, plugins: [ pluginReact({ // [!code highlight:3] swcReactOptions: { 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](/guide/basic/output-structure.md#bundle--bundleless) to keep files unbundled. ::: To emit `.jsx` files, you can configure the JS filename template through [output.filename](/config/rsbuild/output.md#outputfilename) option: ```ts title="rslib.config.ts" twoslash import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { bundle: false, format: 'esm', // [!code highlight:5] output: { filename: { js: '[name].jsx', }, }, }, ], plugins: [ pluginReact({ swcReactOptions: { 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](https://emotion.sh/), you can set `importSource` to `'@emotion/react'`: ```ts title="rslib.config.ts" twoslash import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ // ... ], output: { target: 'web', }, plugins: [ pluginReact({ // [!code highlight:3] swcReactOptions: { 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](https://react.dev/learn/react-compiler) 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](https://npmjs.com/package/react-compiler-runtime) package to run the compiled code on earlier versions. 2. Enable React Compiler through the `reactCompiler` option of `@rsbuild/plugin-react`: ```ts title="rslib.config.ts" import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ plugins: [ pluginReact({ reactCompiler: true, }), ], }); ``` This uses the Rust version of React Compiler integrated in `builtin:swc-loader`, which is around **7-13x faster** than the Babel version. > You can also refer to the [example project](https://github.com/rstackjs/rstack-examples/tree/main/rslib/react-compiler). ### Configuration Pass a config object to customize the React Compiler behavior. For all available options, refer to the [`reactCompiler`](https://rsbuild.rs/plugins/list/plugin-react#reactcompiler) option of `@rsbuild/plugin-react`. ```ts title="rslib.config.ts" import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ plugins: [ pluginReact({ reactCompiler: { compilationMode: 'annotation', }, }), ], }); ``` For React 17 and 18 projects, install [react-compiler-runtime](https://npmjs.com/package/react-compiler-runtime) and specify the `target`: ```ts title="rslib.config.ts" import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ plugins: [ pluginReact({ reactCompiler: { target: '18', // '17' | '18' | '19' }, }), ], }); ``` The `reactCompiler` options are aligned with the React Compiler configuration. For more options, refer to the official [React Compiler configuration documentation](https://react.dev/reference/react-compiler/configuration). ### Using Babel You can also use the Babel plugin published by React Compiler. This is useful if you need Babel-specific integration or options that are not yet available in the SWC transform. Install [@rsbuild/plugin-babel](https://rsbuild.rs/plugins/list/plugin-babel) and [babel-plugin-react-compiler](https://npmjs.com/package/babel-plugin-react-compiler), then register the Babel plugin in your Rslib config file: ```ts title="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'); }, }), ], }); ``` ## SVGR Read [SVGR](/guide/advanced/svgr-files.md) for more details. ## Further reading - [Rsbuild React Plugin](https://rsbuild.rs/plugins/list/plugin-react#swcreactoptionsruntime) - [SWC Compilation - jsc.transform.react](https://swc.rs/docs/configuration/compilation#jsctransformreact) --- url: /guide/solution/reactlynx.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # ReactLynx In this document, you will learn how to build a [ReactLynx](https://lynxjs.org/react/introduction) component library for Lynx applications with Rslib. You can check out ReactLynx related example projects in [Examples](https://github.com/rstackjs/rstack-examples/tree/main/rslib/reactlynx-basic). ## Create a ReactLynx project You can use [`@lynx-js/create-lynx`](https://www.npmjs.com/package/@lynx-js/create-lynx) to create a ReactLynx component library with Rslib: ```sh [npm] npm create @lynx-js/lynx@latest ``` ```sh [yarn] yarn create @lynx-js/lynx ``` ```sh [pnpm] pnpm create @lynx-js/lynx@latest ``` ```sh [bun] bun create @lynx-js/lynx@latest ``` ```sh [deno] deno init --npm @lynx-js/lynx@latest ``` Then select `Rslib` when prompted to "Select build tool", followed by TypeScript or JavaScript. You can also specify the Rslib template directly: ```sh [npm] npm create @lynx-js/lynx@latest my-lib -- --template rslib-react-ts ``` ```sh [yarn] yarn create @lynx-js/lynx my-lib --template rslib-react-ts ``` ```sh [pnpm] pnpm create @lynx-js/lynx@latest my-lib --template rslib-react-ts ``` ```sh [bun] bun create @lynx-js/lynx@latest my-lib --template rslib-react-ts ``` ```sh [deno] deno init --npm @lynx-js/lynx@latest my-lib --template rslib-react-ts ``` ## Use Rslib in an existing project To develop a ReactLynx library, you need to set the [target](/config/rsbuild/output.md#outputtarget) 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. Additionally, ReactLynx component libraries typically need to preserve JSX syntax in the build output so that the application's ReactLynx compiler can process it according to the target environment and build configuration. You can register the Rsbuild [React Plugin](https://rsbuild.rs/plugins/list/plugin-react), set `runtime` to `'preserve'` through [swcReactOptions](https://rsbuild.rs/plugins/list/plugin-react#swcreactoptionsruntime), and set [bundle](/config/lib/bundle.md) to `false` to enable bundleless builds. Also, set `js` to `'[name].jsx'` in [output.filename](/config/rsbuild/output.md#outputfilename) to emit `.jsx` files. For example, configure `rslib.config.ts` as follows: ```ts title="rslib.config.ts" twoslash import { defineConfig } from '@rslib/core'; import { pluginReact } from '@rsbuild/plugin-react'; // [!code highlight] export default defineConfig({ bundle: false, // [!code highlight] // [!code highlight:6] output: { target: 'web', filename: { js: '[name].jsx', }, }, plugins: [ pluginReact({ // [!code highlight:3] swcReactOptions: { runtime: 'preserve', }, }), ], }); ``` ## TypeScript For ReactLynx projects using TypeScript, set `"jsx": "preserve"` and `"jsxImportSource": "@lynx-js/react"` in your `tsconfig.json`, and add `@lynx-js/types` to `types`: ```json title="tsconfig.json" { "compilerOptions": { // [!code highlight:3] "jsx": "preserve", "jsxImportSource": "@lynx-js/react", "types": ["@lynx-js/types", "@rslib/core/types"] } } ``` Set [dts](/config/lib/dts.md) to `true` in `rslib.config.ts` to generate the library's type declarations. ## Output Configure the `.jsx` entry and type declaration entry in `package.json`, and declare ReactLynx and its type dependencies as peer dependencies: ```json title="package.json" { "name": "reactlynx-scroll-list", "type": "module", "exports": { ".": { "types": "./dist/index.d.ts", // [!code ++] "default": "./dist/index.jsx" // [!code ++] } }, "types": "./dist/index.d.ts", // [!code ++] "files": ["dist"], "peerDependencies": { "@lynx-js/react": ">=0.100.0", // [!code ++] "@lynx-js/types": ">=4", // [!code ++] "@types/react": ">=19" // [!code ++] } } ``` ## Testing You can use Rstest to test ReactLynx components. First, install the dependencies needed for testing: ```sh [npm] npm add @rstest/core @rstest/adapter-rslib @lynx-js/react-rsbuild-plugin @testing-library/dom @testing-library/jest-dom happy-dom -D ``` ```sh [yarn] yarn add @rstest/core @rstest/adapter-rslib @lynx-js/react-rsbuild-plugin @testing-library/dom @testing-library/jest-dom happy-dom -D ``` ```sh [pnpm] pnpm add @rstest/core @rstest/adapter-rslib @lynx-js/react-rsbuild-plugin @testing-library/dom @testing-library/jest-dom happy-dom -D ``` ```sh [bun] bun add @rstest/core @rstest/adapter-rslib @lynx-js/react-rsbuild-plugin @testing-library/dom @testing-library/jest-dom happy-dom -D ``` ```sh [deno] deno add npm:@rstest/core npm:@rstest/adapter-rslib npm:@lynx-js/react-rsbuild-plugin npm:@testing-library/dom npm:@testing-library/jest-dom npm:happy-dom -D ``` Use the `withRslibConfig` function from `@rstest/adapter-rslib` to reuse your Rslib configuration. See [Use Rstest](/guide/advanced/rstest.md) for details. Also, use the `withDefaultConfig` function provided by `@lynx-js/react` to load the [ReactLynx test preset](https://lynxjs.org/api/reactlynx-testing-library/#rstest), and register the `pluginReactLynx` plugin from `@lynx-js/react-rsbuild-plugin` to compile JSX: ```ts title="rstest.config.ts" import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin'; // [!code ++] import { withDefaultConfig } from '@lynx-js/react/testing-library/rstest-config'; // [!code ++] import { withRslibConfig } from '@rstest/adapter-rslib'; import { defineConfig } from '@rstest/core'; export default defineConfig({ extends: [withDefaultConfig(), withRslibConfig()], // [!code ++] plugins: [pluginReactLynx()], // [!code ++] }); ``` Once configured, import APIs such as `render`, `screen`, and `fireEvent` from `@lynx-js/react/testing-library` to test component rendering and interactions. See the [ReactLynx testing guide](https://lynxjs.org/react/reactlynx-testing-library.html) for usage details. You can find a complete component testing project in [Examples](https://github.com/rstackjs/rstack-examples/tree/main/rslib/reactlynx-rstest). ## Use the component library ### Use in an application In a Lynx application, you can use a ReactLynx component library by importing it as a package or loading it as an External Bundle. #### Import from a package The component library built and published with the configuration above preserves JSX. After installing it in a Lynx application, you can import and use its components directly, with their JSX processed by the application's ReactLynx compiler. For example, use the `ScrollList` exported by the library: ```tsx title="src/App.tsx" import { ScrollList } from 'reactlynx-scroll-list'; export function App() { return ; } ``` #### Load an external bundle Lynx applications can also load an External Bundle on demand at runtime. Its JSX has already been compiled during the bundle build. When creating the library, you can select the optional `External Bundle` tool or enable it with `--tools external-bundle` in the initialization command: ```sh [npm] npm create @lynx-js/lynx@latest my-lib -- --template rslib-react-ts --tools external-bundle ``` ```sh [yarn] yarn create @lynx-js/lynx my-lib --template rslib-react-ts --tools external-bundle ``` ```sh [pnpm] pnpm create @lynx-js/lynx@latest my-lib --template rslib-react-ts --tools external-bundle ``` ```sh [bun] bun create @lynx-js/lynx@latest my-lib --template rslib-react-ts --tools external-bundle ``` ```sh [deno] deno init --npm @lynx-js/lynx@latest my-lib --template rslib-react-ts --tools external-bundle ``` The generated project includes `rslib.external-bundle.config.*` and a `build:external-bundle` script. Run the following command to compile the library into `dist-external-bundle/.lynx.bundle`: ```sh [npm] npm run build:external-bundle ``` ```sh [yarn] yarn run build:external-bundle ``` ```sh [pnpm] pnpm run build:external-bundle ``` ```sh [bun] bun run build:external-bundle ``` ```sh [deno] deno run build:external-bundle ``` See the [Lynx External Bundle guide](https://lynxjs.org/rspeedy/external-bundle.html) for loading and configuration details. ### Use in a component library You can use existing shared components in your library and preserve JSX for the application to compile. Distributing the package that provides those components as a dependency is recommended. If you need to publish its code with your library, copy output that is ready to use, or rebuild it when its code, styles, or internal imports need processing. ::: tip Type declarations When publishing dependency code with your library by building or copying it, consumers still need to install the dependency if your `.d.ts` files reference its types. Use [dts.bundle.bundledPackages](/config/lib/dts.md#dtsbundlebundledpackages) to bundle those type declarations as well, for example by setting it to `['reactlynx-scroll-list']`. ::: #### Distribute as a dependency (recommended) Declare the library that provides the shared components in `dependencies` or `peerDependencies`. Rslib marks these dependencies as [external](/guide/advanced/third-party-deps.md#default-handling-of-third-party-dependencies) by default, preserving their package imports. When consumers install your library, their package manager installs or reuses packages according to the declared dependencies. The application build then loads these libraries through their package imports and compiles their JSX together. #### Rebuild dependency output If you need to compile the dependency's code or styles, or change its internal imports, use Rslib to build your library and the dependency separately, and use [output.externals](/config/rsbuild/output.md#outputexternals) to rewrite imports. Consider a component library that includes a scroll list adapted from `reactlynx-scroll-list` and other components you write. The configuration has three builds, each identified by an [id](/config/lib/id.md): - `components`: builds the other components you write in bundleless mode, handling component code that needs to preserve JSX. - `bundled-components`: bundles the scroll list entry and the local TS/JS modules it imports, which can adjust exports or include other TS/JS logic. It uses `output.externals` to reference the dependency output. - `vendor`: rebuilds the output of `reactlynx-scroll-list`, preserving JSX and emitting files to `dist/vendor/reactlynx-scroll-list`. In this example, only `src/scroll-list/index.ts` imports `reactlynx-scroll-list`. Other components reference this entry through local imports: ```ts title="src/scroll-list/index.ts" export { ScrollList } from 'reactlynx-scroll-list'; ``` Adjust [outBase](/config/lib/out-base.md) and the entry to match the dependency's actual output, including the code, styles, and static assets to process: ```ts title="rslib.config.ts" import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; const scrollListDir = dirname( fileURLToPath(import.meta.resolve('reactlynx-scroll-list')), ); const reactPlugin = pluginReact({ swcReactOptions: { runtime: 'preserve', }, }); export default defineConfig({ lib: [ { id: 'components', bundle: false, // [!code ++] dts: true, source: { entry: { index: [ './src/**/*', '!./src/scroll-list/**', // [!code ++] ], }, }, plugins: [reactPlugin], }, { id: 'bundled-components', source: { entry: { 'scroll-list/index': './src/scroll-list/index.ts', // [!code ++] }, }, output: { externals: { 'reactlynx-scroll-list': '../vendor/reactlynx-scroll-list/index.jsx', // [!code ++] }, }, }, { id: 'vendor', bundle: false, // [!code ++] outBase: scrollListDir, // [!code ++] source: { entry: { index: `${scrollListDir}/**/*.{js,jsx,css,svg}`, // [!code ++] }, }, output: { distPath: './dist/vendor/reactlynx-scroll-list', // [!code ++] }, plugins: [reactPlugin], }, ], output: { target: 'web', filename: { js: '[name].jsx', }, }, }); ``` The top-level `output.filename` setting gives all builds a consistent `.jsx` extension for their code output. The generated `dist/scroll-list/index.jsx` imports `dist/vendor/reactlynx-scroll-list/index.jsx`, so include the entire `dist` directory when publishing your package. If `reactlynx-scroll-list` imports other component libraries that also need to be distributed with your package, add builds for those packages. In the `vendor` build, use `output.externals` to rewrite their package imports to the paths of their output files. #### Copy dependency output directly If the dependency's output is ready to use and its internal imports need no changes, copy the complete output with [output.copy](/config/rsbuild/output.md#outputcopy). The following configuration builds the library source in bundleless mode to preserve JSX and copies the dependency's output. As above, only `src/scroll-list/index.ts` imports the dependency, and the path in `output.externals` is relative to the generated `dist/scroll-list/index.jsx`: ```ts title="rslib.config.ts" import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; const scrollListDir = dirname( fileURLToPath(import.meta.resolve('reactlynx-scroll-list')), ); export default defineConfig({ bundle: false, dts: true, output: { target: 'web', filename: { js: '[name].jsx', }, externals: { 'reactlynx-scroll-list': '../vendor/reactlynx-scroll-list/index.jsx', // [!code ++] }, copy: [ { from: scrollListDir, // [!code ++] to: 'vendor/reactlynx-scroll-list', // [!code ++] }, ], }, plugins: [ pluginReact({ swcReactOptions: { runtime: 'preserve', }, }), ], }); ``` --- url: /guide/solution/vue.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Vue In this document, you will learn how to build a Vue component library using Rslib. You can check out Vue related example projects in [Examples](https://github.com/rstackjs/rstack-examples/tree/main/rslib). ::: note 1. Only Vue 3 is supported, Vue 2 is not supported. 2. Vue's declaration files are generated by [vue-tsc](https://www.npmjs.com/package/vue-tsc), so [lib.dts](/config/lib/dts.md) / [lib.redirect.dts](/config/lib/redirect.md#redirectdts) / [lib.banner.dts](/config/lib/banner.md#bannerdts) / [lib.footer.dts](/config/lib/footer.md#footerdts) are not effective in Vue projects. ::: ## Create Vue project You can use `create-rslib` to create a project with Rslib + Vue. Just execute the following command: ```sh [npm] npm create rslib@latest ``` ```sh [yarn] yarn create rslib ``` ```sh [pnpm] pnpm create rslib@latest ``` ```sh [bun] bun create rslib@latest ``` Then select `Vue` when prompted to "Select template". ## Use Rslib in an existing project For developing Vue components, you need to set the [target](/config/rsbuild/output.md#outputtarget) to `"web"` in `rslib.config.ts`. This is crucial because Rslib sets `target` to `"node"` by default, which is different from Rsbuild's default target value. To compile Vue (.vue single-file components), you need to register the [@rsbuild/plugin-vue](https://rsbuild.rs/plugins/list/plugin-vue) plugin. This plugin will automatically add the necessary configurations for Vue build. For example, register in `rslib.config.ts`: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; import { pluginVue } from '@rsbuild/plugin-vue'; // [!code highlight] export default defineConfig({ lib: [ // ... ], // [!code highlight:4] output: { target: 'web', }, plugins: [pluginVue(/** options here */)], }); ``` For more configuration options, please refer to the [@rsbuild/plugin-vue documentation](https://rsbuild.rs/plugins/list/plugin-vue). --- url: /guide/solution/svelte.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Svelte In this document, you will learn how to build a Svelte component library using Rslib. You can check out Svelte related example projects in [Examples](https://github.com/rstackjs/rstack-examples/tree/main/rslib). ## Create Svelte project You can use `create-rslib` to create a project with Rslib + Svelte. Just execute the following command: ```sh [npm] npm create rslib@latest ``` ```sh [yarn] yarn create rslib ``` ```sh [pnpm] pnpm create rslib@latest ``` ```sh [bun] bun create rslib@latest ``` Then select `Svelte` when prompted to "Select template". ## Use Rslib in an existing project For developing Svelte components, you need to set the [target](/config/rsbuild/output.md#outputtarget) to `"web"` in `rslib.config.ts`. This is crucial because Rslib sets `target` to `"node"` by default, which is different from Rsbuild's default target value. To compile Svelte (`.svelte` files), you need to register the [@rsbuild/plugin-svelte](https://rsbuild.rs/plugins/list/plugin-svelte) plugin. This plugin integrates [svelte-loader](https://github.com/sveltejs/svelte-loader) internally and will automatically add the necessary configurations for Svelte build. For example, register in `rslib.config.ts`: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; import { pluginSvelte } from '@rsbuild/plugin-svelte'; // [!code highlight] export default defineConfig({ lib: [ // ... ], // [!code highlight:4] output: { target: 'web', }, plugins: [pluginSvelte(/** options here */)], }); ``` For more configuration options, refer to the [@rsbuild/plugin-svelte documentation](https://rsbuild.rs/plugins/list/plugin-svelte). ## Declaration files ::: note Svelte declaration files are generated by [`svelte2tsx`](https://www.npmjs.com/package/svelte2tsx), so [lib.dts](/config/lib/dts.md) / [lib.redirect.dts](/config/lib/redirect.md#redirectdts) / [lib.banner.dts](/config/lib/banner.md#bannerdts) / [lib.footer.dts](/config/lib/footer.md#footerdts) are not effective in Svelte projects. ::: Rslib provides a plugin example for generating types in Svelte projects: [svelteDtsPlugin](https://github.com/web-infra-dev/rslib/blob/main/packages/create-rslib/template-svelte-ts/scripts/rslib-plugin-svelte-dts.ts). The plugin calls the `emitDts` method provided by [svelte2tsx](https://www.npmjs.com/package/svelte2tsx) after build to generate declaration files for `.svelte` files. If you create a Svelte TypeScript project with `create-rslib`, this plugin is already included in the template. For an existing project, you can use it like this: ```ts title="rslib.config.ts" import { svelteDtsPlugin } from './scripts/rslib-plugin-svelte-dts'; export default { plugins: [svelteDtsPlugin()], }; ``` `svelteDtsPlugin` passes the following options through to the [svelte2tsx](https://www.npmjs.com/package/svelte2tsx) [emitDts](https://github.com/sveltejs/language-tools/blob/master/packages/svelte2tsx/src/emitDts.ts) config: - `declarationDir`: The output directory for declaration files. Defaults to `./dist`. - `libRoot`: The source directory to emit declaration files for. Defaults to `./src`. - `tsconfig`: The tsconfig path used for declaration generation. Defaults to [source.tsconfigPath](/config/rsbuild/source.md#sourcetsconfigpath). - `svelteShimsPath`: The path to the svelte2tsx shims type file. Defaults to `svelte2tsx/svelte-shims-v4.d.ts`. If you need type checking, install the [svelte-check](https://www.npmjs.com/package/svelte-check) npm package and add a `check` command to `package.json`: ```json title="package.json" { "scripts": { "check": "svelte-check" }, "devDependencies": { "svelte-check": "^4.7.6" } } ``` --- url: /guide/solution/solid.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Solid In this document, you will learn how to build a Solid component library using Rslib. You can check out Solid related example projects in [Examples](https://github.com/rstackjs/rstack-examples/tree/main/rslib). ## Create Solid project You can use `create-rslib` to create a project with Rslib + Solid. Just execute the following command: ```sh [npm] npm create rslib@latest ``` ```sh [yarn] yarn create rslib ``` ```sh [pnpm] pnpm create rslib@latest ``` ```sh [bun] bun create rslib@latest ``` Then select `Solid` when prompted to "Select template". ## Use Rslib in an existing project To develop a Solid library, you need to set the [target](/config/rsbuild/output.md#outputtarget) to `"web"` in `rslib.config.ts`. This is crucial because Rslib sets the `target` to `"node"` by default. To compile Solid JSX, you need to register both the [@rsbuild/plugin-babel](https://rsbuild.rs/plugins/list/plugin-babel) and [@rsbuild/plugin-solid](https://rsbuild.rs/plugins/list/plugin-solid) plugins. The Solid plugin uses [`babel-preset-solid`](https://www.npmjs.com/package/babel-preset-solid) to transform JSX into Solid's runtime DOM expressions. ```json title="package.json" { "devDependencies": { "@rsbuild/plugin-babel": "^2.0.0", "@rsbuild/plugin-solid": "^1.2.2", "solid-js": "^1.9.9" }, "peerDependencies": { "solid-js": "^1.8.0" } } ``` ```ts title="rslib.config.ts" import { pluginBabel } from '@rsbuild/plugin-babel'; // [!code highlight] import { pluginSolid } from '@rsbuild/plugin-solid'; // [!code highlight] import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { bundle: false, dts: true, // [!code highlight:6] plugins: [ pluginBabel({ include: /\.(?:jsx|tsx)$/, }), pluginSolid(), ], }, ], // [!code highlight:3] output: { target: 'web', }, }); ``` ## Output Solid component libraries usually ship two types of outputs: - **Pre-compiled output**: JSX has already been transformed by `babel-preset-solid` into Solid runtime calls, such as `template()` and `insert()`. Application projects that use this component library can import this output directly, without configuring Solid JSX compilation. - **JSX source output**: the library build does not compile Solid JSX. Instead, it preserves the original JSX syntax and exposes it through the `"solid"` condition name in `package.json` for the application-side toolchain. When an application project that uses this component library can compile Solid JSX (for example, an Rsbuild project with `@rsbuild/plugin-solid` installed), module resolution will hit the `"solid"` condition name, read the JSX source output, and recompile it for the application's runtime target: browser apps compile it into client-side DOM rendering code (`generate: 'dom'`), while SSR frameworks compile it into server-side rendering code (`generate: 'ssr'`). Application projects without Solid JSX compilation configured fall back to the pre-compiled `"default"` entry. ```ts title="rslib.config.ts" import { pluginBabel } from '@rsbuild/plugin-babel'; import { pluginSolid } from '@rsbuild/plugin-solid'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { // Compile JSX into Solid runtime calls, such as template(), insert(), and delegateEvents(). dts: true, plugins: [ pluginBabel({ include: /\.(?:jsx|tsx)$/, }), pluginSolid(), ], }, { // Preserve JSX syntax for the "solid" condition name. output: { filename: { js: '[name].jsx', }, }, tools: { swc: { detectSyntax: 'auto', jsc: { transform: { react: { // Keep JSX syntax in the output. runtime: 'preserve', }, }, }, }, rspack: { module: { parser: { javascript: { // Allow Rspack to parse preserved JSX. jsx: true, }, }, }, }, }, }, ], bundle: false, output: { target: 'web', }, }); ``` Then configure the `"exports"` field in `package.json`: ```json title="package.json" { // [!code highlight:7] "exports": { ".": { "types": "./dist/index.d.ts", "solid": "./dist/index.jsx", "default": "./dist/index.js" } } } ``` ## TypeScript For Solid projects using TypeScript, set `"jsx": "preserve"` and `"jsxImportSource": "solid-js"` in your `tsconfig.json`: ```json title="tsconfig.json" { "compilerOptions": { // [!code highlight:2] "jsx": "preserve", "jsxImportSource": "solid-js" } } ``` ## SSR Most Solid component libraries do not publish a separate SSR build by default. Instead, downstream frameworks resolve the `"solid"` condition name, get the preserved JSX output, and compile it for their own target. If you intentionally need a pre-compiled SSR output, configure `pluginSolid` with the `solid.generate` option set to `'ssr'`: ```ts title="rslib.config.ts" export default defineConfig({ lib: [ // ... existing compiled and source entries // [!code highlight:21] { id: 'server', bundle: false, output: { distPath: { root: './dist/server', }, }, plugins: [ pluginBabel({ include: /\.(?:jsx|tsx)$/, }), pluginSolid({ solid: { generate: 'ssr', hydratable: true, }, }), ], }, ], }); ``` --- url: /guide/basic/cli.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # CLI Rslib comes with a lightweight CLI that includes commands such as [rslib](#rslib) and [rslib inspect](#rslib-inspect). ## All commands To view all available CLI commands, run the following command in the project directory: ```bash npx rslib -h ``` The output is shown below: ```bash Usage: $ rslib [command] [options] Commands: build build the library for production (default if no command is given) inspect inspect the Rsbuild / Rspack configs of Rslib projects mf-dev start Rsbuild dev server of Module Federation format ``` ## Common flags Rslib CLI provides several common flags that can be used with all commands: | Flag | Description | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-c, --config ` | Specify the configuration file, can be a relative or absolute path, see [Specify config file](/guide/basic/configure-rslib.md#specify-config-file) | | `--config-loader ` | Set the config file loader (`auto` \| `jiti` \| `native`), see [Specify config loader](/guide/basic/configure-rslib.md#specify-config-loader) | | `--env-dir ` | Specify the directory to load `.env` files, see [Rsbuild - Env directory](https://rsbuild.rs/guide/advanced/env-vars#env-directory) | | `--env-mode ` | Specify the env mode to load the `.env.[mode]` file, see [Rsbuild - Env mode](https://rsbuild.rs/guide/advanced/env-vars#env-mode) | | `-h, --help` | Display help for command | | `--lib ` | Specify the library to run commands (repeatable, e.g. `--lib esm --lib cjs`), see [lib.id](/config/lib/id.md) to learn how to get or set the ID of the library | | `--log-level ` | Set the log level (`info` \| `warn` \| `error` \| `silent`), see [logLevel](/config/rsbuild/log-level.md) | | `--no-env` | Disable loading of `.env` files | | `-r, --root ` | Specify the project root directory, can be an absolute path or a path relative to cwd | ## rslib The `rslib` command will build the outputs for production in the `dist/` directory by default. `rslib build` is an alias for the `rslib` command. ```bash Usage: $ rslib Options: -w, --watch turn on watch mode, watch for changes and rebuild --entry set entry file or pattern (repeatable) --dist-path set output directory --bundle enable bundle mode (use --no-bundle to disable) --format specify the output format (esm | cjs | umd | mf | iife) --syntax set build syntax target (repeatable) --target set runtime target (web | node) --dts emit declaration files (use --no-dts to disable) --externals add package to externals (repeatable) --minify minify output (use --no-minify to disable) --clean clean output directory before build (use --no-clean to disable) --auto-extension control automatic extension redirect (use --no-auto-extension to disable) --auto-external control automatic dependency externalization (use --no-auto-external to disable) --tsconfig use specific tsconfig (relative to project root) ``` :::note If the [Rslib configuration file](/guide/basic/configure-rslib.md#configuration-file) is not present in your project, the CLI will automatically use the default configuration containing only a single [lib](/config/lib/index.md) and apply all build options from the command line. You can add a configuration file once you need a more complex configuration or want to build outputs in multiple formats. ::: ### Watch mode Use `rslib --watch` or `rslib -w` to enable watch mode. Rslib watches for source file changes and automatically rebuilds when they change. If you need to adjust the configuration based on whether watch mode is enabled, check `process.argv`: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; const isWatch = process.argv.some((arg) => arg === '--watch' || arg === '-w'); export default defineConfig({ source: { alias: { '@request': isWatch ? './src/request.dev.js' : './src/request.prod.js', }, }, }); ``` ## rslib inspect The `rslib inspect` command inspects a project's Rslib config and the corresponding Rsbuild and Rspack configs. ```bash Usage: $ rslib inspect Options: --mode set the build mode (development | production) --output set the output path for inspection results (default: ".rsbuild") --verbose show complete function definitions in output ``` When you run the command `npx rslib inspect` in the project root directory, the following files will be generated in the `dist/.rsbuild` directory of the project: - `rsbuild.config.mjs`: Represents the Rsbuild configuration used during the build. - `rspack.config.esm.mjs`: Represents the Rspack configuration used during the build. - `rslib.config.mjs`: Represents the resolved Rslib configuration. ```text ➜ npx rslib inspect config inspection completed, generated files: - Rsbuild config: /project/dist/.rsbuild/rsbuild.config.mjs - Rspack Config (esm): /project/dist/.rsbuild/rspack.config.esm.mjs - Rslib Config: /project/dist/.rsbuild/rslib.config.mjs ``` ### Setting mode By default, `mode` is inferred from `process.env.NODE_ENV`: it is `'development'` when `NODE_ENV` is `'development'`, and `'production'` otherwise. When `mode` is `'production'`, the inspect command outputs production mode configurations for all libraries. You can add the `--mode development` option to output development mode configurations for libraries with [format](/config/lib/format.md) set to `mf`: ```bash rslib inspect --mode development ``` ### Verbose content By default, the inspect command omits function bodies in the configuration object. To output complete function content, add the `--verbose` option: ```bash rslib inspect --verbose ``` ### Multiple output formats If the current project has multiple output formats, such as ESM artifact and CJS artifact simultaneously, multiple Rspack configuration files will be generated in the `dist/.rsbuild` directory. ```text ➜ npx rslib inspect config inspection completed, generated files: - Rsbuild config (esm): /project/dist/.rsbuild/rsbuild.config.esm.mjs - Rsbuild config (cjs): /project/dist/.rsbuild/rsbuild.config.cjs.mjs - Rspack Config (esm): /project/dist/.rsbuild/rspack.config.esm.mjs - Rspack Config (cjs): /project/dist/.rsbuild/rspack.config.cjs.mjs - Rslib Config: /project/dist/.rsbuild/rslib.config.mjs ``` ## rslib mf-dev The `rslib mf-dev` command is utilized to start Rsbuild dev server for the [Module Federation](/guide/advanced/module-federation.md) format. This enables you to develop and debug your mf format module within the host app. --- url: /guide/basic/configure-rslib.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Configure Rslib Rslib configuration lets you define library outputs and control how each output is built. ## Configuration structure Rslib configuration consists of two types of options: - [Lib configurations](/config/lib.md) describe library outputs, including their output formats, output structures, and syntax targets. - [Rsbuild configurations](/config/rsbuild.md) control the underlying compilation and build behavior, including module resolution, source processing, and related plugins. The `lib` field is an optional array of objects. Each object corresponds to one output and can contain both types of configuration above. Configurations inside a `lib` item apply only to that output, while configurations outside the `lib` field are top-level configurations shared across `lib` outputs. Rslib merges the top-level configuration with each `lib` item according to the [configuration merge rules](https://rsbuild.rs/api/javascript-api/core#merge-rules). ### Lib configurations Lib configurations can be specified in a `lib` item to configure a specific output. [Some lib configurations](/config/lib.md#top-level-lib-configurations) can also be placed outside the `lib` field as top-level configuration shared across `lib` outputs. For example, set [`syntax`](/config/lib/syntax.md) to `es2020` for the CJS output and use top-level configuration to set `syntax` to `es2021` for the other outputs: ```js title="rslib.config.mjs" export default { lib: [ { format: 'esm', }, { format: 'cjs', syntax: 'es2020', }, ], syntax: 'es2021', }; ``` After merging, `syntax` is `es2021` for the ESM output and `es2020` for the CJS output. When you only need to generate a single ESM output using the default configuration, you can omit the `lib` field. This is equivalent to setting `lib: [{}]`. ### Rsbuild configurations Rsbuild configurations can be placed outside the `lib` field as top-level configuration shared across `lib` outputs, or inside a `lib` item to configure a specific output. For example, set the ESM output's [output.target](/config/rsbuild/output.md#outputtarget) to `'web'`, and use top-level configuration to set `output.target` to `'node'` for the other outputs: ```js title="rslib.config.mjs" export default { lib: [ { format: 'esm', output: { target: 'web', }, }, { format: 'cjs', }, ], output: { target: 'node', }, }; ``` After merging, `output.target` is `'web'` for the ESM output and `'node'` for the CJS output. :::info - Rslib generates the Rsbuild [environments](https://rsbuild.rs/config/environments) configuration internally. You can enable [debug mode](#debug-mode) or run the [rslib inspect](/guide/basic/cli.md#rslib-inspect) command to view the final generated configuration. - You can find detailed descriptions of all configuration options on the [Configuration overview](/config/index.md) page. ::: ## Configuration file When you use the CLI of Rslib, Rslib will automatically read the configuration file in the root directory of the current project and resolve it in the following order: - `rslib.config.mjs` - `rslib.config.ts` - `rslib.config.js` - `rslib.config.cjs` - `rslib.config.mts` - `rslib.config.cts` We recommend using the `.mjs` or `.ts` format for the configuration file and importing the `defineConfig` utility function from `@rslib/core`. It provides friendly TypeScript type hints and autocompletion, which can help you avoid errors in the configuration. For example, in `rslib.config.ts`, you can define the Rslib [syntax](/config/lib/syntax.md) configuration and the Rsbuild [output.target](https://rsbuild.rs/config/output/target#outputtarget) configuration: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'esm', syntax: 'es2021', }, ], output: { target: 'node', }, }); ``` If you are developing a non-TypeScript project, you can use the `.mjs` format for the configuration file. :::tip When you use the `.ts`, `.mts`, and `.cts` extensions, Rslib will use [jiti](https://github.com/unjs/jiti) to load configuration files, providing interoperability between ESM and CommonJS. The behavior of module resolution differs slightly from the native behavior of Node.js. ::: ## Specify config file Rslib CLI uses the `--config` option to specify the config file, which can be set to a relative path or an absolute path. For example, if you need to use the `rslib.prod.config.mjs` file when running `build`, you can add the following scripts to `package.json`: ```json title="package.json" { "scripts": { "build": "rslib --config rslib.prod.config.mjs" } } ``` You can also abbreviate the `--config` option to `-c`: ```bash rslib -c rslib.prod.config.mjs ``` ## Specify config loader Rslib provides three ways to load configuration files: - `jiti`: When you use a configuration file with the `.ts`, `.mts`, and `.cts` extensions, Rslib will use [jiti](https://github.com/unjs/jiti) to load configuration files, providing interoperability between ESM and CommonJS. The behavior of module resolution differs slightly from the native behavior of Node.js. - `native`: Use Node.js native loader to load the configuration file. This can ensure that the module resolution behavior is consistent with the native behavior of Node.js and has better performance. This requires that your JavaScript runtime already natively supports TypeScript. For example, Node.js v22.6.0+ already natively supports TypeScript, you can use the following command to use the Node.js native loader to load the configuration file: ```bash # Node.js >= v22.18.0 # No need to set --experimental-strip-types npx rslib --config-loader native # Node.js v22.6.0 - v22.17.1 # Need to set --experimental-strip-types NODE_OPTIONS="--experimental-strip-types" npx rslib --config-loader native ``` - `auto`(Default): Use Node.js's native loader to load configuration files first, fallback to using jiti if it fails. ### About Node.js native loader When using Node.js's native loader, please note the following limitations: 1. When importing JSON files, you need to use import attributes: ```ts import pkgJson from './package.json' with { type: 'json' }; // ✅ Correct import pkgJson from './package.json'; // ❌ Incorrect ``` 2. When importing TypeScript files, you need to include the `.ts` extension: ```ts import baseConfig from './rslib.base.config.ts'; // ✅ Correct import baseConfig from './rslib.base.config'; // ❌ Incorrect ``` > See [Node.js - Running TypeScript Natively](https://nodejs.org/en/learn/typescript/run-natively#running-typescript-natively) for more details. ## Using environment variables In the configuration file, you can use Node.js environment variables to dynamically set different configurations: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'esm', }, ], source: { alias: { '@language': process.env.LANGUAGE === 'en' ? './src/language/en.js' : './src/language/zh.js', }, }, }); ``` ## Configure Rsbuild Rslib allows you to use most of the Rsbuild configurations. Currently, the `environments` config is not supported because it is generated internally by Rslib. - Refer to [Rsbuild Configuration](/config/rsbuild/index.md) for common Rsbuild configurations. - Refer to [Rsbuild Documentation](https://rsbuild.rs/config/) for all Rsbuild configurations. ## Configure Rspack Rslib is built on top of Rsbuild and Rsbuild supports directly modifying the Rspack configuration object and also supports modifying the built-in Rspack configuration of Rsbuild through `rspack-chain`. This means you can configure Rspack related configurations in an Rslib project as well. For more details, refer to [Configure Rspack](https://rsbuild.rs/guide/configuration/rspack). ## Debug mode You can add the `DEBUG=rslib` environment variable when building to enable Rslib's debug mode. ```bash DEBUG=rslib pnpm build ``` In debug mode, Rslib will output additional log information and write the final Rsbuild config and Rspack config after processing by Rslib to the output directory, making it convenient for developers to view and debug. Here is an example of a library that sets both CJS and ESM formats: ``` Inspect config succeed, open following files to view the content: - Rsbuild Config (esm): /project/dist/.rsbuild/rsbuild.config.esm.mjs - Rsbuild Config (cjs): /project/dist/.rsbuild/rsbuild.config.cjs.mjs - Rspack Config (esm): /project/dist/.rsbuild/rspack.config.esm.mjs - Rspack Config (cjs): /project/dist/.rsbuild/rspack.config.cjs.mjs - Rslib Config: /project/dist/.rsbuild/rslib.config.mjs ``` - Open the generated `/dist/.rsbuild/rsbuild.config.esm.mjs` file to see the complete content of the Rsbuild config. - Open the generated `/dist/.rsbuild/rspack.config.esm.mjs` file to see the complete content of the Rspack config. - Open the generated `/dist/.rsbuild/rslib.config.mjs` file to see the complete content of the Rslib config. --- url: /guide/basic/typescript.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Use TypeScript Rslib supports TypeScript by default, allowing you to directly use `.ts` and `.tsx` files in your projects. ## TypeScript transpilation Rslib uses SWC by default for transpiling TypeScript code, and it also supports switching to Babel for transpilation. ### isolatedModules Unlike the native TypeScript compiler, tools like SWC and Babel compile each file separately and cannot determine whether an imported name is a type or a value. Therefore, when using TypeScript in Rslib, you need to enable the [isolatedModules](https://typescriptlang.org/tsconfig/#isolatedModules) option in your `tsconfig.json` file: ```json title="tsconfig.json" { "compilerOptions": { "isolatedModules": true } } ``` This option can help you avoid using certain syntax that cannot be correctly compiled by SWC and Babel, such as cross-file type references. It will guide you to correct the corresponding usage: ```ts // Wrong export { SomeType } from './types'; // Correct export type { SomeType } from './types'; ``` > See [SWC - Migrating from tsc](https://swc.rs/docs/migrating-from-tsc) for more details about the differences between SWC and tsc. ## Preset types `@rslib/core` provides some preset type definitions, including CSS Modules, static assets, `import.meta` and other types. Add the preset types to [`compilerOptions.types`](https://www.typescriptlang.org/tsconfig/#types) in `tsconfig.json`: ```json title="tsconfig.json" { "compilerOptions": { "types": ["@rslib/core/types"] } } ``` If your project already has `compilerOptions.types`, append `@rslib/core/types` to the existing list. > Rslib's preset types are the same as Rsbuild's preset types. See Rsbuild's [types.d.ts](https://github.com/web-infra-dev/rsbuild/blob/main/packages/core/types.d.ts) for the complete type definitions. ## Type checking When transpiling TypeScript code using tools like SWC and Babel, type checking is not performed. Rslib provides the [lib.dts](/config/lib/dts.md) configuration item for generating TypeScript declaration files, and type checking is performed by default during the generation process. You can skip type checking by setting the [noCheck](https://www.typescriptlang.org/tsconfig/#noCheck) configuration item to `true` in the `tsconfig.json` file. ## tsconfig.json path Rslib by default reads the `tsconfig.json` file from the root directory. You can use [source.tsconfigPath](/config/rsbuild/source.md#sourcetsconfigpath) to configure a custom `tsconfig.json` file path. ```ts title="rslib.config.ts" export default { lib: [ // ... ], source: { tsconfigPath: './tsconfig.custom.json', }, }; ``` ## Decorators version Rslib uses the [`2023-11`](https://rsbuild.rs/config/source/decorators#2023-11) version of the decorators by default. If [experimentalDecorators](https://www.typescriptlang.org/tsconfig/#experimentalDecorators) is enabled in `tsconfig.json`, Rslib will set [source.decorators.version](/config/rsbuild/source.md#sourcedecorators) to `legacy` to use the legacy decorators. --- url: /guide/basic/output-format.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Output format There are multiple supported output formats for the generated JavaScript files in Rslib: [ESM](#esm--cjs), [CJS](#esm--cjs), [UMD](#umd), [MF](#mf), and [IIFE](#iife). In this chapter, we will introduce the differences between these formats and how to choose the right one for your library. ## ESM / CJS Library authors need to carefully consider which module formats to support. Let's understand ESM (ECMAScript Modules) and CJS (CommonJS) and when to use them. ### What are ESM and CJS? - **ESM**: - **CommonJS**: ::: tip Read the [Node.js Package Configuration Guide](https://nodejs.github.io/package-examples/) to learn more about ESM and CJS, including file structure, `package.json` configuration, module interoperability, and best practices. ::: ### Choose module formats The choice of module format usually depends on how the package will be consumed. For new packages, prefer pure ESM and add a dual ESM/CJS build only when there is a clear compatibility requirement. #### Prefer pure ESM ESM is the standard JavaScript module format. It is supported by modern browsers, Node.js, and mainstream build tools, and enables static analysis and tree shaking. Compared with CommonJS, `import` and `export` statements are more concise and easier to read. Additionally, maintaining one format reduces build configuration, package exports, and test combinations. If consumers still use CommonJS and `package.json#exports` allows `require()` to resolve the ESM entry, they can load a pure ESM package directly with `require()` on [Node.js `^20.19.0` or `>=22.12.0`](https://nodejs.org/api/modules.html#loading-ecmascript-modules-using-require), provided that neither the entry nor its dependencies use top-level `await`. Library authors do not need to publish a separate CJS output only for these consumers: ```js const packageExports = require('pure-esm-package'); ``` #### Publish dual ESM/CJS for compatibility Consider publishing both ESM and CJS when: - CommonJS consumers use Node.js versions, tools, or runtimes that cannot load ESM synchronously with `require()`. - Consumers explicitly require a separate CJS file. Dual formats provide broader compatibility and help consumers migrate gradually to ESM, but require separate builds, export mappings, and tests. Loading both formats can also create separate instances of the same package, leading to inconsistent state or identity checks. Confirm that target consumers need CJS before adding it. ## UMD ### What is UMD? UMD stands for [Universal Module Definition](https://github.com/umdjs/umd), a pattern for writing JavaScript modules that can work universally across different environments, such as both the browser and Node.js. Its primary goal is to ensure compatibility with the most popular module systems, including AMD (Asynchronous Module Definition), CommonJS (CJS), and browser globals. ### When to use UMD? If you are building a library that needs to be used in both the browser and Node.js environments, UMD is a good choice. UMD can be used as a standalone script tag in the browser or as a CommonJS module in Node.js. A detailed answer from StackOverflow: [What is the Universal Module Definition (UMD)?](https://stackoverflow.com/a/77284527/8063488) > However, for frontend libraries, you still offer a single file for convenience, that users can download (from a CDN) and directly embed in their web pages. This still commonly employs a UMD pattern, it's just no longer written/copied by the library author into their source code, but added automatically by the transpiler/bundler. > > And similarly, for backend/universal libraries that are supposed to work in > Node.js, you still also distribute a commonjs module build via npm to support > all the users who still use a legacy version of Node.js (and don't want/need > to employ a transpiler themselves). This is less common nowadays for new > libraries, but existing ones try hard to stay backwards-compatible and not > cause applications to break. ### How to build a UMD library? - Set the [lib.format](/config/lib/format.md) to `umd` in the Rslib configuration file. - If the library need to be exported with a name, set [lib.umdName](/config/lib/umd-name.md) to the name of the UMD library. - Use [output.externals](/config/rsbuild/output.md#outputexternals) to specify the external dependencies that the UMD library depends on, [lib.autoExtension](/config/lib/auto-extension.md) is enabled by default for UMD. ### Examples The following Rslib config is an example to build a UMD library. - `lib.format: 'umd'`: instruct Rslib to build in UMD format. - `lib.umdName: 'RslibUmdExample'`: set the export name of the UMD library. - `output.externals.react: 'React'`: specify the external dependency `react` could be accessed by `window.React`. - `runtime: 'classic'`: use the classic runtime of React to support applications that using React version under 18. ```ts title="rslib.config.ts" import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { // [!code highlight:6] format: 'umd', umdName: 'RslibUmdExample', output: { externals: { react: 'React', }, distPath: './dist/umd', }, }, ], output: { target: 'web', }, plugins: [ pluginReact({ swcReactOptions: { runtime: 'classic', // [!code highlight] }, }), ], }); ``` ## MF ### What is MF? MF stands for Module Federation. Module Federation is an architectural pattern for JavaScript application decomposition (similar to microservices on the server-side), allowing you to share code and resources between multiple JavaScript applications (or micro-frontends). See [Module Federation](https://rsbuild.rs/guide/advanced/module-federation) for more details. ## IIFE The iife format stands for "immediately-invoked function expression" and is intended to be run in the browser. Wrapping your code in a function expression ensures that any variables in your code don't accidentally conflict with variables in the global scope. If your entry point has exports that you want to expose as a global in the browser, you can configure that global's name using the global name setting. In IIFE format, [output.globalObject](https://rspack.rs/config/output#outputglobalobject) is set to [globalThis](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) by default. The `import` statements that match [externals](/config/rsbuild/output.md#outputexternals) in the source code will be transformed to access properties through `globalThis`. You can override [output.globalObject](https://rspack.rs/config/output#outputglobalobject) to any value. When specifying the `iife` format, the source code and corresponding output are as follows: ```js title="source code" // parent-sdk is marked as externals // externals: ['parent-sdk'] import { version } from 'parent-sdk'; alert(version); ``` ```js title="IIFE output" ( () => { const external_parent_sdk_namespaceObject = globalThis['parent-sdk']; alert(external_parent_sdk_namespaceObject.version); }, )(); ``` --- url: /guide/basic/output-structure.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Output structure ## bundle / bundleless So first let's understand bundle and bundleless. Bundle refers to the process of packaging the build outputs, which may be a single file or multiple files based on a certain [code splitting strategy](https://rspack.rs/guide/optimization/code-splitting). Bundleless, on the other hand, means that each source file is compiled and built separately, but not bundled together. Each output file can be found with its corresponding source code file. The process of bundleless build can also be understood as the process of code transformation of source files only. ![rslib-bundleless-mode](https://assets.rspack.rs/rslib/rslib-bundleless-mode.png) They have their own benefits. - bundle can reduce the size of build artifacts and also prebundle dependencies to reduce the size of installed dependencies and increase security. Packaging libraries in advance can speed up application project builds. - bundleless maintains the original file structure and is more conducive to debugging and tree shaking. :::warning bundleless is a single-file compilation mode, so for referencing and exporting types, you need to add the `type` keyword. For example, `import type { A } from './types'`. Please refer to [TypeScript - isolatedModules](/guide/basic/typescript.md#isolatedmodules) for more information. ::: You can specify whether to bundle using the [bundle](/config/lib/bundle.md) option, which is set to `true` by default. --- url: /guide/advanced/third-party-deps.md --- > 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, }, }, ], }, }, }, }); ``` --- url: /guide/advanced/output-compatibility.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Output compatibility This chapter introduces how to specify which target environment should be supported. ## Syntax downgrade In Rslib, you can configure the syntax to which JavaScript and CSS will be downgraded by setting [lib.syntax](/config/lib/syntax.md). This configuration supports setting the ECMAScript version directly, such as `es2015`, `es2022`, etc., and also supports setting the query syntax of [Browserslist](https://browsersl.ist/), such as `last 2 versions`, `> 1%`, `node >= 16`, `chrome >= 80`, etc. It should be noted that Rslib does not read the Browserslist related configuration files (such as `.browserslistrc` or the `browserslist` field in `package.json`). You can override by setting [output.overrideBrowserslist](/config/rsbuild/output.md#outputoverridebrowserslist) which has a higher priority than [lib.syntax](/config/lib/syntax.md). ## Polyfill Before dealing with compatibility issues, it is recommended that you understand the following background knowledge to better handle related issues. Check out the background knowledge on [syntax transpilation and API polyfill](https://rsbuild.rs/guide/advanced/browser-compatibility#syntax-downgrade-and-api-downgrade). ### Browser Normally, we don't need to inject polyfill for npm packages, this step should be done on the web application framework side, but in some scenarios we need to inject polyfill in order to make our library run directly in low version browsers. Note that this plugin does not transform your code syntax, it only injects polyfill for unsupported functions used in your code, importing them as normal functions instead of polluting the global. You need to install the [core-js-pure](https://www.npmjs.com/package/core-js-pure) dependency. #### Set up The polyfill relies on Babel to inject the polyfill code, so you need to install the [Rsbuild Babel plugin](https://rsbuild.rs/plugins/list/plugin-babel) and [babel-plugin-polyfill-corejs3](https://www.npmjs.com/package/babel-plugin-polyfill-corejs3) to inject the polyfill code. ```sh [npm] npm add @rsbuild/plugin-babel babel-plugin-polyfill-corejs3 -D ``` ```sh [yarn] yarn add @rsbuild/plugin-babel babel-plugin-polyfill-corejs3 -D ``` ```sh [pnpm] pnpm add @rsbuild/plugin-babel babel-plugin-polyfill-corejs3 -D ``` ```sh [bun] bun add @rsbuild/plugin-babel babel-plugin-polyfill-corejs3 -D ``` ```sh [deno] deno add npm:@rsbuild/plugin-babel npm:babel-plugin-polyfill-corejs3 -D ``` And install [core-js-pure](https://www.npmjs.com/package/core-js-pure) as the runtime relied code. ```sh [npm] npm add core-js-pure ``` ```sh [yarn] yarn add core-js-pure ``` ```sh [pnpm] pnpm add core-js-pure ``` ```sh [bun] bun add core-js-pure ``` ```sh [deno] deno add npm:core-js-pure ``` Configure the Babel plugin with polyfill options, set the [targets](https://babeljs.io/docs/options#targets) field to specify the target browser version. ```ts title="rslib.config.ts" import { pluginBabel } from '@rsbuild/plugin-babel'; // [!code highlight] import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'esm', }, ], plugins: [ // [!code highlight:14] pluginBabel({ babelLoaderOptions: { plugins: [ [ require('babel-plugin-polyfill-corejs3'), { method: 'usage-pure', targets: { ie: '10' }, version: '3.29', }, ], ], }, }), ], }); ``` #### Configurations Check out [babel-plugin-polyfill-corejs3](https://www.npmjs.com/package/babel-plugin-polyfill-corejs3) documentation for more details. ### Node.js :::tip About Node Polyfill Normally, we don't need to use Node libs on the browser side. However, it is possible to use some Node libs when the code will run on both the Node side and the browser side, and Node Polyfill provides browser versions of polyfills for these Node libs. ::: By using [@rsbuild/plugin-node-polyfill](https://github.com/rstackjs/rsbuild-plugin-node-polyfill), Node core libs polyfills are automatically injected into the browser-side, allowing you to use these modules on the browser side with confidence. #### Set up Rslib uses [@rsbuild/plugin-node-polyfill](https://github.com/rstackjs/rsbuild-plugin-node-polyfill) to provide the Node Polyfill feature. ```sh [npm] npm add @rsbuild/plugin-node-polyfill -D ``` ```sh [yarn] yarn add @rsbuild/plugin-node-polyfill -D ``` ```sh [pnpm] pnpm add @rsbuild/plugin-node-polyfill -D ``` ```sh [bun] bun add @rsbuild/plugin-node-polyfill -D ``` ```sh [deno] deno add npm:@rsbuild/plugin-node-polyfill -D ``` Then add the plugin into the plugins field. ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; import { pluginNodePolyfill } from '@rsbuild/plugin-node-polyfill'; export default defineConfig({ lib: [{ format: 'esm' }], plugins: [pluginNodePolyfill()], }); ``` #### Configurations - For projects with `bundle` enabled, the Node Polyfill will be injected and included in the output. - For projects with `bundle` disabled, polyfills are not injected into the output by default. To avoid inlining the polyfill in every module, the modules are externalized and need to be added to dependencies manually, follow these steps: 1. Configure `output.external` with `resolvedPolyfillToModules`, which you can import from [@rsbuild/plugin-node-polyfill](https://github.com/rstackjs/rsbuild-plugin-node-polyfill). This will externalize the polyfill modules to the installed polyfill dependencies. 2. Install used polyfill modules as dependencies. With the above steps, every usage of the polyfill module will be replaced by the corresponding module in the `externals` field. Checkout the of the example for more details. Check out the documentation of [@rsbuild/plugin-node-polyfill](https://github.com/rstackjs/rsbuild-plugin-node-polyfill), all the configurations are applicable for Rslib. --- url: /guide/advanced/env-vars.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Environment variables Rslib supports injecting environment variables or expressions into code during the build. This is useful for distinguishing runtime environments, replacing constants, and similar scenarios. This page explains how to use environment variables in Rslib. ## Default environment variables Depending on the [output format](/guide/basic/output-format.md) specified by [format](/config/lib/format.md), Rslib either preserves source environment variables in the build output or replaces them with specific values at build time. The behavior is as follows: | format | import.meta.env.\* | process.env.\* | | ---------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | esm | Preserved | Preserved | | cjs | `import.meta.env` is replaced with `undefined` | Preserved | | umd / iife | Replaced |
  • `process.env.NODE_ENV`: replaced with the build process's `NODE_ENV`, which defaults to `'production'`
  • [process.env.BASE\_URL](https://rsbuild.rs/guide/advanced/env-vars#processenvbase_url) and [process.env.ASSET\_PREFIX](https://rsbuild.rs/guide/advanced/env-vars#processenvasset_prefix): replaced
  • Other variables: preserved
| | mf | Replaced |
  • `process.env.NODE_ENV`: by default, replaced with `'production'` during [build](/guide/basic/cli.md#rslib) and `'development'` during [mf-dev](/guide/basic/cli.md#rslib-mf-dev)
  • [process.env.BASE\_URL](https://rsbuild.rs/guide/advanced/env-vars#processenvbase_url) and [process.env.ASSET\_PREFIX](https://rsbuild.rs/guide/advanced/env-vars#processenvasset_prefix): replaced
  • Other variables: preserved
| :::note Environment variables preserved in the build output are typically replaced by a downstream build tool or resolved by the target runtime; variables replaced at build time use [Rsbuild's default values](https://rsbuild.rs/guide/advanced/env-vars#default-variables). ::: ### process.env.NODE\_ENV By default, Rslib automatically sets the `process.env.NODE_ENV` environment variable: - It is set to `'production'` when running [build](/guide/basic/cli.md#rslib) or calling [rslib.build()](/api/javascript-api/instance.md#rslibbuild), including in watch mode. - It is set to `'development'` when running [mf-dev](/guide/basic/cli.md#rslib-mf-dev) or calling [rslib.startMFDevServer()](/api/javascript-api/instance.md#rslibstartmfdevserver). These defaults are set in the current Node.js process. You can override them by setting `NODE_ENV` before running Rslib. Configuration files, plugins, and their dependencies can read this environment variable and adjust their behavior accordingly. Whether `process.env.NODE_ENV` is replaced in the output follows the rules in the table above. Build and optimization strategies are determined by the internal `mode`, which does not change with this environment variable. See [Optimization and chunks](/config/default-behavior.md#optimization-and-chunks) for details. To override the default handling in the build output, such as disabling replacement or specifying a custom replacement value, use [tools.rspack](/config/rsbuild/tools.md#toolsrspack) to configure Rspack's [optimization.nodeEnv](https://rspack.rs/config/optimization#optimizationnodeenv): ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ tools: { rspack: { optimization: { nodeEnv: false, }, }, }, }); ``` ## `.env` files The Rslib CLI loads `.env` files from the project root by default. You can adjust this behavior with the following CLI options: - `--env-mode `: Load the corresponding `.env.[mode]` file. - `--env-dir `: Specify the directory containing the `.env` files. - `--no-env`: Disable loading `.env` files. After loading, all environment variables are added to the current Node.js process, so they can be accessed through `process.env` in `rslib.config.*`. By default, only variables prefixed with `PUBLIC_` are used to replace matching environment variable expressions at build time. For supported `.env` file types, loading order, and override rules, see [Rsbuild - `.env` files](https://rsbuild.rs/guide/advanced/env-vars#env-file). For Public variable handling rules, see [Rsbuild - Public variables](https://rsbuild.rs/guide/advanced/env-vars#public-variables). ## Using define To replace a global identifier in your code with another value or expression at build time, use [source.define](/config/rsbuild/source.md#sourcedefine). For example: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ source: { define: { 'import.meta.env.FOO': JSON.stringify('foo'), 'process.env.BAR': JSON.stringify('bar'), }, }, }); ``` :::tip - Explicit definitions take precedence over Rslib's default handling and are replaced in every output format. - Values passed to `source.define` are code fragments, so string values must be converted with `JSON.stringify()`. - Define only the properties you need instead of replacing the entire `process.env` object. ::: For environment variable type declarations, see [Rsbuild - Type declarations](https://rsbuild.rs/guide/advanced/env-vars#type-declarations). --- url: /guide/advanced/dts.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # Declaration files This chapter introduces what [TypeScript Declaration Files](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html) are and how to generate declaration files in Rslib. ## What is declaration files TypeScript Declaration Files provide type information for JavaScript code. Declaration files typically have a `.d.ts` extension. They allow the TypeScript compiler to understand the type structure of JavaScript code, enabling features like: 1. **Type Checking**: Provide type information for JavaScript code, helping developers catch potential type errors at compile time. 2. **Code Completion**: Enhance code editor features like autocomplete and code navigation. 3. **Documentation Generation**: Generate documentation for JavaScript code, providing better developer experience. 4. **IDE Support**: Improve the developer experience in IDEs like Visual Studio Code, WebStorm, and others. 5. **Library Consumption**: Make it easier for users to use and understand your library. ## What are bundle declaration files and bundleless declaration files ### Bundle declaration files Bundle declaration files involves bundling multiple TypeScript declaration files into a single declaration file. - **Pros:** - **Simplified Management**: Simplifies the management and referencing of type files. - **Easy Distribution**: Reduces the number of files users need to handle when using the library. - **Cons:** - **Complex Generation**: Generating and maintaining a single bundle file can become complex in large projects. - **Debugging Challenges**: Debugging type issues may not be as intuitive as with separate files. ### Bundleless declaration files Bundleless declaration files involves generating a separate declaration file for each module in the library, just like `tsc` does. - **Pros:** - **Modular**: Each module has its own type definitions, making maintenance and debugging easier. - **Flexibility**: Suitable for large projects, avoiding the complexity of a single file. - **Cons:** - **Multiple Files**: Users may need to handle multiple declaration files when using the library. - **Complex Management**: May require additional configuration to correctly reference all files. ## How to generate declaration files in Rslib Rslib's declaration generation flow can be split into two steps: 1. Type generation, that is, generate bundleless declaration files. Rslib supports the following three methods: - [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) - [tsgo](https://github.com/microsoft/typescript-go) - [isolatedDeclarations](https://www.typescriptlang.org/tsconfig/#isolatedDeclarations) 2. Type bundling, that is, generate bundled declaration files (optional). When [dts.bundle](/config/lib/dts.md#dtsbundle) is enabled, Rslib bundles the generated declaration files with [API Extractor](https://api-extractor.com/). ### Generate bundleless declaration files Bundleless declaration files can be generated in the following three ways: | Method | Configuration | Type checking | Output scope | Speed | | --------------------------------- | ------------------------------------------------ | ------------- | ---------------------------------------------- | ------- | | TypeScript Compiler API (default) | `dts: true` or `dts: { bundle: false }` | Yes | Determined by `tsconfig.json` | Slower | | tsgo | [`dts.tsgo`](/config/lib/dts.md#dtstsgo) | Yes | Determined by `tsconfig.json` | Fast | | isolatedDeclarations | [`dts.isolated`](/config/lib/dts.md#dtsisolated) | No | Modules included in the build dependency graph | Fastest | #### TypeScript compiler API This is the default behavior. It is mostly the same as running `tsc`: it generates declaration files and performs type checking, but it is relatively slower. ```ts title="rslib.config.ts" export default { lib: [ { dts: true; // [!code highlight] // or // [!code highlight:3] dts: { bundle: false; } }, ], }; ``` #### tsgo Using [native TypeScript](https://github.com/microsoft/typescript-go) to generate declaration files keeps type checking enabled while significantly speeding up declaration generation. When [dts.tsgo](/config/lib/dts.md#dtstsgo) is unset, Rslib enables it automatically when TypeScript 7+ is detected. ```sh [npm] npm add typescript@latest -D ``` ```sh [yarn] yarn add typescript@latest -D ``` ```sh [pnpm] pnpm add typescript@latest -D ``` ```sh [bun] bun add typescript@latest -D ``` ```sh [deno] deno add npm:typescript@latest -D ``` To ensure consistency during local development, you need to install the corresponding [VS Code Preview Extension](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.native-preview) and add the following setting to VS Code: ```json title=".vscode/settings.json" { "typescript.experimental.useTsgo": true } ``` #### isolatedDeclarations Enabling [dts.isolated](/config/lib/dts.md#dtsisolated) uses Rspack's built-in SWC fast\_dts capability to generate declaration files. This method is the fastest, but it does not perform type checking and only emits declaration files for modules included in the build dependency graph. ```ts title="rslib.config.ts" export default { lib: [ { dts: { isolated: true, // [!code highlight] }, }, ], }; ``` When enabling this option, we recommend also enabling [isolatedDeclarations](https://www.typescriptlang.org/tsconfig/#isolatedDeclarations) in `tsconfig.json`: ```json title="tsconfig.json" { "compilerOptions": { "isolatedDeclarations": true } } ``` ### Generate bundle declaration files 1. Install `@microsoft/api-extractor` as a development dependency, which is the underlying tool used for bundling declaration files. ```sh [npm] npm add @microsoft/api-extractor -D ``` ```sh [yarn] yarn add @microsoft/api-extractor -D ``` ```sh [pnpm] pnpm add @microsoft/api-extractor -D ``` ```sh [bun] bun add @microsoft/api-extractor -D ``` ```sh [deno] deno add npm:@microsoft/api-extractor -D ``` 2. Configure in the Rslib config file: ```ts title="rslib.config.ts" export default { lib: [ { // [!code highlight:3] dts: { bundle: true; } }, ], }; ``` ### Notes During the generation of declaration files, Rslib will automatically enforce some configuration options in `tsconfig.json` to ensure that the [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) or [tsgo](https://github.com/microsoft/typescript-go) generates only declaration files. ```json { "compilerOptions": { "noEmit": false, "declaration": true, "emitDeclarationOnly": true } } ``` The priority from highest to lowest of final output directory of declaration files: - The configuration option [dts.distPath](/config/lib/dts.md#dtsdistpath) - The configuration option `declarationDir` in `tsconfig.json` - The configuration option [output.distPath](/config/rsbuild/output.md#outputdistpath) or [output.distPath.root](/config/rsbuild/output.md#outputdistpath) ## Related configuration | Configuration item | Description | | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | [dts.bundle](/config/lib/dts.md#dtsbundle) | Whether to bundle the declaration files. | | [dts.distPath](/config/lib/dts.md#dtsdistpath) | The output directory of declaration files. | | [dts.build](/config/lib/dts.md#dtsbuild) | Whether to generate declaration files with building the project references. | | [dts.abortOnError](/config/lib/dts.md#dtsabortonerror) | Whether to abort the build process when an error occurs during declaration files generation. | | [dts.autoExtension](/config/lib/dts.md#dtsautoextension) | Whether to automatically set the declaration file extension based on the [format](/config/lib/format.md) option. | | [dts.alias](/config/lib/dts.md#dtsalias) | The path alias of the declaration files. | | [dts.isolated](/config/lib/dts.md#dtsisolated) | Whether to generate declaration files with `isolatedDeclarations`. | | [dts.tsgo](/config/lib/dts.md#dtstsgo) | Whether to generate declaration files with [tsgo](https://github.com/microsoft/typescript-go). | | [banner.dts](/config/lib/banner.md#bannerdts) | Inject content into the top of each declaration output file. | | [footer.dts](/config/lib/footer.md#footerdts) | Inject content into the bottom of each declaration file. | | [redirect.dts.path](/config/lib/redirect.md#redirectdtspath) | Whether to automatically redirect the import paths of TypeScript declaration output files. | | [redirect.dts.extension](/config/lib/redirect.md#redirectdtsextension) | Whether to automatically redirect the file extension to import paths based on the TypeScript declaration output files. | --- url: /guide/advanced/css.md --- > For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt. # CSS Rslib provides out-of-the-box support for CSS, including CSS Modules, CSS preprocessors, PostCSS, CSS inlining, Lightning CSS, and CSS compression. Rslib also provides several configurations to customize CSS file processing. ## Import CSS You can import CSS files directly in JavaScript files. ```js title="src/index.js" import './index.css'; ``` You should note that the default value of Rslib's [output.target](/config/rsbuild/output.md#outputtarget) is `'node'`. If you need to handle CSS styles, you need to set it to `'web'`. ```ts title="rslib.config.ts" export default { output: { target: 'web', }, }; ``` When [format](/config/lib/format.md) is `'cjs'` or `'esm'`, Rslib will apply different processing methods to CSS based on the [bundle](/config/lib/bundle.md) configuration. ### Bundle mode In `bundle` mode (default behavior), Rslib will bundle the CSS into a separate file and will not preserve the `import` statement referencing the CSS in the output JavaScript file. This is a common practice for community library development, which is friendlier to Server-Side Rendering (SSR) and avoids parsing errors caused by loading CSS files in the Node.js environment. Furthermore, for upstream applications using the library, on-demand style importing can be achieved through relevant plugins or configurations, such as Rsbuild's [source.transformImport](https://rsbuild.rs/config/source/transform-import). If you want to preserve the `import` statement referencing the CSS, you can use the following methods: 1. **Use banner**: Configure [banner.js](/config/lib/banner.md#bannerjs) to add `import './index.css';` to the top of the output JavaScript file. ```ts title="rslib.config.ts" export default { lib: [ { banner: { js: "import './index.css';", }, }, ], }; ``` For more complex scenarios, such as when code splitting generates multiple chunk files, you can use Rspack's [BannerPlugin](https://rspack.rs/plugins/webpack/banner-plugin) to precisely control which modules need to add a banner, avoiding adding it to all chunks. ```ts title="rslib.config.ts" export default { lib: [ { tools: { rspack: { plugins: [ new rspack.BannerPlugin({ banner: "import './index.css';", raw: true, test: /^index\.js$/, }), ], }, }, }, ], }; ``` 2. **Inline styles**: Enable [output.injectStyles](/config/rsbuild/output.md#outputinjectstyles) to inject CSS directly into the JavaScript runtime. 3. **Use bundleless mode**: Set [bundle](/config/lib/bundle.md) to `false` to preserve the source code file structure and reference relationships. ### Bundleless mode In `bundleless` mode ([bundle](/config/lib/bundle.md) set to `false`), Rslib will preserve the source code file structure and reference relationships. This means that the `import` statement referencing the CSS will be preserved in the output JavaScript file. This method is friendlier to build tools and facilitates Tree Shaking and on-demand importing of styles. Here is an example usage, assuming the source code is as follows: **src/index.ts** ```ts import './index.css'; export const component = () => {}; ``` **src/index.css** ```css .title { color: red; } ``` Based on the [output structure](/guide/basic/output-structure.md) configuration in the config file, the output will be as follows: **bundle** **dist/index.mjs** ```js const component = () => {}; export { component }; ``` **dist/index.css** ```css .title { color: red; } ``` **bundleless** **dist/index.mjs** ```js import './index.css'; const component = () => {}; export { component }; ``` **dist/index.css** ```css .title { color: red; } ``` ## CSS Modules Rslib supports CSS Modules by default without additional configuration. Our convention is to use the `[name].module.css` filename to enable CSS Modules. The following style files are considered CSS Modules: - `*.module.css` - `*.module.less` - `*.module.sass` - `*.module.scss` - `*.module.styl` - `*.module.stylus` Read the [CSS Modules](https://rsbuild.rs/guide/styling/css-modules) chapter to understand the complete usage of CSS Modules. Assuming the source code is as follows: **src/index.ts** ```tsx import styles from './index.module.css'; console.log(styles.title); ``` **src/index.module.css** ```css .title { color: red; } ``` The output will be as follows: **bundle** **dist/index.mjs** ```js const index_module = { title: 'title-aQjbKQ', }; console.log(index_module.title); ``` **dist/index.css** ```css .title-aQjbKQ { color: red; } ``` **bundleless** **dist/index.mjs** ```js import index_module from './index.module.mjs'; console.log(index_module.title); ``` **dist/index.module.mjs** ```js import './index_module.css'; const index_module = { title: 'title-aQjbKQ', }; export { index_module as default }; ``` **dist/index_module.css** ```css .title-aQjbKQ { color: red; } ``` ## CSS preprocessors Rslib supports popular CSS preprocessors through plugins, including Sass, Less, and Stylus. See how to use them: - [Sass Plugin](https://rsbuild.rs/plugins/list/plugin-sass) - [Less Plugin](https://rsbuild.rs/plugins/list/plugin-less) - [Stylus Plugin](https://github.com/rstackjs/rsbuild-plugin-stylus) Taking the Sass plugin as an example, you can install the plugin via the following command: ```sh [npm] npm add @rsbuild/plugin-sass -D ``` ```sh [yarn] yarn add @rsbuild/plugin-sass -D ``` ```sh [pnpm] pnpm add @rsbuild/plugin-sass -D ``` ```sh [bun] bun add @rsbuild/plugin-sass -D ``` ```sh [deno] deno add npm:@rsbuild/plugin-sass -D ``` Then register the plugin in the `rslib.config.ts` file: ```ts title="rslib.config.ts" import { pluginSass } from '@rsbuild/plugin-sass'; export default { plugins: [pluginSass()], }; ``` After registering the plugin, you can import `*.scss`, `*.sass`, `*.module.scss`, or `*.module.sass` files in your code without adding other configurations. ## PostCSS Rslib supports transforming CSS code through [PostCSS](https://postcss.org/). You can configure PostCSS in the following ways: ### Configuration file Rslib uses [postcss-load-config](https://github.com/postcss/postcss-load-config) to load the PostCSS configuration file in the root directory of the current project, such as postcss.config.cjs: ```js title="postcss.config.cjs" module.exports = { plugins: { 'postcss-px-to-viewport': { viewportWidth: 375, }, }, }; ``` `postcss-load-config` supports multiple file formats, including but not limited to the following file names: - postcss.config.js - postcss.config.mjs - postcss.config.cjs - postcss.config.ts - ... ### tools.postcss You can also configure the postcss-loader through [tools.postcss](/config/rsbuild/tools.md#toolspostcss) option, which supports modifying the built-in configuration through a function, for example: ```ts title="rslib.config.ts" export default { tools: { postcss: (opts) => { const viewportPlugin = require('postcss-px-to-viewport')({ viewportWidth: 375, }); opts.postcssOptions.plugins.push(viewportPlugin); }, }, }; ``` ### Configuration priority - When you configure both the `postcss.config.js` file and the `tools.postcss` option, both will take effect, and the `tools.postcss` option will take precedence. - If there is no `postcss.config.js` file in the project and the `tools.postcss` option is not configured, Rslib will not register `postcss-loader`. ## Tailwind CSS ### Tailwind CSS v4 #### Using the Rsbuild plugin We recommend using the [@rsbuild/plugin-tailwindcss](https://rsbuild.rs/plugins/list/plugin-tailwindcss) plugin to integrate [Tailwind CSS v4](https://tailwindcss.com/) in Rslib. 1. Install `@rsbuild/plugin-tailwindcss` and `tailwindcss` packages: ```sh [npm] npm add @rsbuild/plugin-tailwindcss tailwindcss -D ``` ```sh [yarn] yarn add @rsbuild/plugin-tailwindcss tailwindcss -D ``` ```sh [pnpm] pnpm add @rsbuild/plugin-tailwindcss tailwindcss -D ``` ```sh [bun] bun add @rsbuild/plugin-tailwindcss tailwindcss -D ``` ```sh [deno] deno add npm:@rsbuild/plugin-tailwindcss npm:tailwindcss -D ``` 2. Register the plugin in the `rslib.config.ts` file: ```ts title="rslib.config.ts" import { pluginTailwindcss } from '@rsbuild/plugin-tailwindcss'; export default { plugins: [pluginTailwindcss()], }; ``` 3. Add an `@import` to your CSS entry file that imports Tailwind CSS. ```css title="src/index.css" @import 'tailwindcss'; ``` :::tip Tailwind CSS v4 cannot be used with CSS preprocessors like Sass, Less, or Stylus. You need to place the `@import 'tailwindcss';` statement at the beginning of your `.css` file, see [Tailwind CSS - Compatibility](https://tailwindcss.com/docs/compatibility#sass-less-and-stylus) for more details. ::: 4. Use Tailwind's utility classes in any component or HTML, for example: ```html

Hello world!

``` For more usage, please refer to the [@rsbuild/plugin-tailwindcss documentation](https://rsbuild.rs/plugins/list/plugin-tailwindcss). #### Using the PostCSS plugin Rslib has built-in support for PostCSS, so projects that already have a PostCSS setup can install `tailwindcss` and [@tailwindcss/postcss](https://www.npmjs.com/package/@tailwindcss/postcss) to integrate Tailwind CSS: ```sh [npm] npm add tailwindcss @tailwindcss/postcss -D ``` ```sh [yarn] yarn add tailwindcss @tailwindcss/postcss -D ``` ```sh [pnpm] pnpm add tailwindcss @tailwindcss/postcss -D ``` ```sh [bun] bun add tailwindcss @tailwindcss/postcss -D ``` ```sh [deno] deno add npm:tailwindcss npm:@tailwindcss/postcss -D ``` You can register the Tailwind CSS PostCSS plugin through a [PostCSS configuration file](https://npmjs.com/package/postcss-loader#config) or [tools.postcss](/config/rsbuild/tools.md#toolspostcss). ```js title="postcss.config.mjs" export default { plugins: { '@tailwindcss/postcss': {}, }, }; ``` ### Tailwind CSS v3 Refer to [Use Tailwind CSS v3](https://rsbuild.rs/guide/styling/tailwindcss-v3). ## Inline CSS files By default (when [bundle](/config/lib/bundle.md) is `true`), Rslib will extract CSS into a separate `.css` file and output it to the dist directory. To inline styles into your JS file, set [output.injectStyles](/config/rsbuild/output.md#outputinjectstyles) to `true` to disable CSS extraction logic. When the JS file is requested by the browser, JS dynamically inserts the `