--- url: /guide/start/index.md --- # Introduction Rslib is a library development tool that leverages the well-designed configurations and plugins of [Rsbuild](https://rsbuild.rs), empowering library developers to take advantage of the extensive knowledge and ecosystem of webpack and Rspack. Rslib provides a comprehensive set of build features for library development, including: - **Compilation of diverse languages**: TypeScript, JSX, Sass, Less, CSS Modules, Wasm, and more. - **Flexible build modes**: Bundle and bundleless options to meet varying needs. - **Multiple output formats**: ESM, CJS, and UMD for maximum compatibility. - **Declaration file generation**: Including isolated declarations. - **Advanced features**: Module Federation, asset compression, PostCSS, Lightning CSS, and more. ## ✨ 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**: Rslib aims to simplify library development by offering ready-to-use build capabilities, enabling developers to kickstart their library projects with minimal configuration. - **Performance Oriented**: Rslib integrates high-performance Rust-based tools from the community, including [Rspack](https://rspack.rs/), [SWC](https://swc.rs/) and [Lightning CSS](https://lightningcss.dev/), to deliver first-class build speed and development experience. - **Plugin Ecosystem**: Powered by Rsbuild, Rslib benefits from a lightweight plugin system and a collection of high-quality official plugins. Furthermore, Rsbuild's compatibility with most webpack plugins and all Rspack plugins allows library developers to seamlessly integrate existing community or in-house plugins into their library projects. ## 🎯 Ecosystem Rslib is implemented based on Rsbuild and fully reuses the capabilities and ecosystem of Rsbuild. The following diagram illustrates the relationship between Rslib and other tools in the ecosystem: ![Rspack stack layers](https://assets.rspack.rs/rsbuild/assets/rspack-stack-layers.png) ## 🦀 Rstack Rstack is a unified JavaScript toolchain centered on Rspack, with high performance and consistent architecture. | 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. - [rstack-examples](https://github.com/rstackjs/rstack-examples): Examples for Rstack. - [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. --- url: /guide/start/quick-start.md --- # 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 >= 0.20 requires Node.js version 20.19+, 22.12+. - Rslib \< 0.20 requires Node.js 18.12.0 or higher. ::: ## 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. After creating the project, do the following: - Run `git init` to initialize a Git repository. - 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 dual ESM/CJS package | Node.js dual ESM/CJS package | | Node.js pure ESM package | Node.js pure ESM package | | React | React component library | | Vue | Vue component library | | Svelte | Svelte 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 --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-dual-js, node-dual-ts, node-esm-js, node-esm-ts, react-js, react-ts, vue-js, vue-ts, svelte-js, svelte-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 Modern.js Module](/guide/migration/modernjs-module.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 --- # 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 --- # 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 --- # 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. - [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” under the title 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. ::: tip If you are using Claude Code, you can create a `CLAUDE.md` file and reference the `AGENTS.md` file in it. ```markdown title="CLAUDE.md" @AGENTS.md ``` ::: --- url: /guide/solution/index.md --- # 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. 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 --- # 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 Node.js project effortlessly with minimal configuration. For example, in `rslib.config.ts`: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'esm', output: { distPath: './dist/esm', }, }, { format: 'cjs', output: { distPath: './dist/cjs', }, }, ], }); ``` ## 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 --- # 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/vue.md --- # 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 --- # 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.4.8" } } ``` --- url: /guide/basic/cli.md --- # 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. ::: ### Environment variables Rslib supports injecting environment variables or expressions into the code during the build, which is helpful for distinguishing running environments or replacing constants. You can see more details in [Rsbuild - Environment variables](https://rsbuild.rs/guide/advanced/env-vars). By default, Rslib sets the `process.env.NODE_ENV` environment variable, which is always `'production'` during the build. If you need to distinguish watch mode to dynamically set different configurations, you can set as follows: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; const isWatch = process.argv.includes('--watch'); export default defineConfig({ lib: [ { format: 'esm', }, ], source: { alias: { '@request': isWatch ? './src/request.dev.js' : './src/request.prod.js', }, }, }); ``` ::: note - If [format](/config/lib/format.md) is `esm` or `cjs`, `process.env.NODE_ENV` in source code will be preserved in the build output. - If [format](/config/lib/format.md) is `mf` or `umd`, `process.env.NODE_ENV` in source code will be replaced to ensure that the output can run in the browser. ::: ## rslib inspect The `rslib inspect` command is used to view the Rsbuild config and Rspack config of the Rslib project. ```bash Usage: $ rslib inspect Options: --output specify inspect content output path (default: ".rsbuild") --verbose show full 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.web.mjs`: Represents the Rspack configuration used during the build. - `rslib.config.mjs`: Represents the final Rslib configuration after normalization. ```text ➜ npx rslib inspect Inspect config succeed, open following files to view the content: - 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 ``` ### Verbose content By default, the inspect command omits the content of functions in the configuration object. You can add the `--verbose` option to output the complete content of functions: ```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 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 ``` ## 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 --- # Configure Rslib Rslib's configuration is based on Rsbuild, which means that you can use all of Rsbuild configurations, as well as the `lib` configuration specific to Rslib. ## Configuration structure Rslib provides the `lib` option to configure the library outputs. It is an array, and each object is used to describe a format of the output. For example, output ESM and CJS formats, and use `es2021` syntax: ```js title="rslib.config.mjs" export default { lib: [ { format: 'esm', syntax: 'es2021' }, { format: 'cjs', syntax: 'es2021' }, ], }; ``` ### Common Rsbuild configurations You can set common Rsbuild configurations outside the `lib` field, which will be inherited by each configuration object inside the `lib` field. For example, set the [output.target](/config/rsbuild/output.md#outputtarget) of Rsbuild to `web`, which will affect the output of all `lib` configuration objects: ```js title="rslib.config.mjs" export default { lib: [ { format: 'esm', syntax: 'es2021' }, { format: 'cjs', syntax: 'es2021' }, ], output: { target: 'web', }, }; ``` ### Separate Rsbuild configurations In the `lib` field, you can set separate Rsbuild configurations for each output format, which will override the common Rsbuild configurations outside the `lib` field. For example, separately set the [output.target](/config/rsbuild/output.md#outputtarget) of the ESM output to `web`: ```js title="rslib.config.mjs" export default { lib: [ // The target of the ESM output is `web` { format: 'esm', output: { target: 'web', }, }, // The CJS output inherits the common configuration and target is `node` { format: 'cjs', }, ], output: { target: 'node', }, }; ``` Rslib will generate the [environments](https://rsbuild.rs/config/environments) configuration of Rsbuild internally, you can run [rslib inspect](/guide/basic/cli.md#rslib-inspect) command to view the final generated configuration. You can also refer to the [Configuration Overview](/config/index.md) page to view the detailed introduction of all configurations. ## 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 --- # 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. You can create a `src/env.d.ts` file to reference it: ```ts title="src/env.d.ts" /// ``` ## 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 - Since v0.21.0, Rslib uses the [`2023-11`](https://rsbuild.rs/config/source/decorators#2023-11) version of the decorators by default. - Before v0.21.0, Rslib uses the [`2022-03`](https://rsbuild.rs/config/source/decorators#2022-03) 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 --- # 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 For different shapes of libraries, the choice of module format may vary. Here are two common scenarios: #### ship [pure ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) package shipping only ESM is the best choice for libraries that are intended to be used in modern environments, such as browser applications or Node.js applications that support ESM. However, if the upstream library is in format of CJS, they only can import pure ESM by using dynamic import like `const pureEsmLib = await import('pure-esm-lib')`. - **Pros:** - ESM is the official JavaScript standard, making it more future-proof and widely supported across environments. - ESM enables static analysis, which facilitates optimizations like tree-shaking to remove unused code. - The syntax is cleaner and more intuitive, with import and export statements that are easier to read compared to CommonJS. - ESM allows for better compatibility across both browser and server environments, making it ideal for isomorphic or universal JavaScript applications. - **Cons:** - ESM modules are loaded asynchronously, which can complicate conditional imports and lazy loading in some cases. - Some Node.js tools and libraries still have limited or incomplete support for ESM, requiring workarounds or additional configuration. - You must explicitly include file extensions in import paths, which can be cumbersome, especially when working with TypeScript or other transpiled languages. #### ship [ESM & CJS (dual)](https://antfu.me/posts/publish-esm-and-cjs#compatibility) package The community is migrating to ESM, but there are still many projects using CJS. If you want to support both ESM and CJS, you can publish a dual package. For most library authors, offering dual formats is a safer and smoother way to access the best of both worlds. You could read antfu' blog post [Publish ESM and CJS packages](https://antfu.me/posts/publish-esm-and-cjs) for more details. - **Pros:** - Wider compatibility: Dual packages support both modern ESM environments and legacy CJS environments, ensuring broader usage across different ecosystems. - Gradual migration: Developers can gradually transition from CJS to ESM without breaking existing projects, allowing for smoother adoption of the new standard. - Flexibility for consumers: Users of the package can choose which module system best fits their project, providing flexibility in different build tools and environments. - Cross-runtime support: Dual packages can work in multiple runtimes, such as Node.js and browsers, without requiring additional bundling or transpilation. - **Cons:** - Increased complexity: Maintaining two module formats adds complexity to the build process, requiring additional configuration and testing to ensure both versions work correctly. - Dual package hazard: Mixing ESM and CJS can lead to issues such as broken instanceof checks or unexpected behavior when dependencies are loaded in different formats. ## 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 --- # 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/basic/upgrade-rslib.md --- # Upgrade Rslib This section explains how to upgrade the project's Rslib dependencies to the latest version. :::info Rslib is still in 0.x version stage, and the API may change frequently. We recommend upgrading to the latest version to access new features and bug fixes. ::: ## Using taze We recommend using [Taze](https://github.com/antfu-collective/taze) to upgrade the Rslib version. Taze is a CLI tool for updating npm dependencies. ### Usage Run the following command to upgrade all dependencies that include `rslib` and `rsbuild` in their names: ```bash npx taze major --include "/(rsbuild|rslib)/" -w ``` :::tip Rslib has not yet reached version 1.0.0, so you need to add the `major` parameter when updating. ::: The result will look similar to: ```bash rslib - 2 major, 1 patch @rsbuild/plugin-react dev ~2mo ^1.0.1 → ^1.0.6 @rslib/core dev ~7d ^0.0.15 → ^0.0.16 rsbuild-plugin-dts dev ~7d ^0.0.15 → ^0.0.16 ℹ changes written to package.json, run npm i to install updates. ``` You can also adjust the `include` pattern to match specific packages, for example, to upgrade only packages under the `@rslib` scope: ```bash npx taze --include /@rslib/ -w ``` ### Options Here are some examples of using taze options. - In a monorepo, you can add the `-r` option to upgrade recursively: ```bash npx taze --include /(rsbuild|rslib)/ -w -r ``` - Add `-l` to upgrade locked versions: ```bash npx taze --include /(rsbuild|rslib)/ -w -l ``` - To upgrade to a major version: ```bash npx taze major --include /(rsbuild|rslib)/ -w ``` > For more options, please refer to the [taze documentation](https://github.com/antfu-collective/taze). --- url: /guide/advanced/third-party-deps.md --- # 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. ### Example If 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: - [lib.autoExternal](/config/lib/auto-external.md) - [output.externals](/config/rsbuild/output.md#outputexternals) ## Exclude specified third-party dependencies The configuration described above allows you to implement more fine-grained handling of third-party dependencies. For example, when we need to leave only certain dependencies unbundled, we can configure it as follows. :::tip In this case, some dependencies may not be suitable for bundling. If so, you can handle it as follows. ::: ```ts export default defineConfig({ lib: [ { // ... autoExternal: true, output: { externals: ['pkg-1', /pkg-2/], }, // ... }, ], }); ``` --- url: /guide/advanced/output-compatibility.md --- # 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. By default, the syntax is set to `ESNext`, which will only supports only the latest version of mainstream browsers (Chrome / Firefox / Edge / macOS Safari / iOS Safari) or Node.js according to [output.target](/config/rsbuild/output.md#outputtarget). 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/dts.md --- # 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 [TypeScript Go](https://github.com/microsoft/typescript-go) to generate declaration files can preserve type checking while significantly improving the speed of declaration generation. After installing TypeScript 7 or higher, Rslib will automatically enable [dts.tsgo](/config/lib/dts.md#dtstsgo). ```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 ``` You can also install `@typescript/native-preview` and enable `dts.tsgo` in the Rslib config file. ```sh [npm] npm add @typescript/native-preview -D ``` ```sh [yarn] yarn add @typescript/native-preview -D ``` ```sh [pnpm] pnpm add @typescript/native-preview -D ``` ```sh [bun] bun add @typescript/native-preview -D ``` ```sh [deno] deno add npm:@typescript/native-preview -D ``` ```ts title="rslib.config.ts" export default { lib: [ { dts: { tsgo: true, // [!code highlight] }, }, ], }; ``` :::note The `@typescript/native-preview` usage is deprecated and kept only for compatibility. Prefer installing `typescript@latest` to use tsgo. ::: 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 --- # 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://rsbuild.rs/plugins/list/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 `