ReactLynx
In this document, you will learn how to build a ReactLynx component library for Lynx applications with Rslib. You can check out ReactLynx related example projects in Examples.
Create a ReactLynx project
You can use @lynx-js/create-lynx to create a ReactLynx component library with Rslib:
Then select Rslib when prompted to "Select build tool", followed by TypeScript or JavaScript. You can also specify the Rslib template directly:
Use Rslib in an existing project
To develop a ReactLynx library, you need to set the target to "web" in rslib.config.ts. This is crucial because Rslib sets the target to "node" by default, which differs from the default target of Rsbuild.
Additionally, ReactLynx component libraries typically need to preserve JSX syntax in the build output so that the application's ReactLynx compiler can process it according to the target environment and build configuration. You can register the Rsbuild React Plugin, set runtime to 'preserve' through swcReactOptions, and set bundle to false to enable bundleless builds. Also, set js to '[name].jsx' in output.filename to emit .jsx files.
For example, configure rslib.config.ts as follows:
TypeScript
For ReactLynx projects using TypeScript, set "jsx": "preserve" and "jsxImportSource": "@lynx-js/react" in your tsconfig.json, and add @lynx-js/types to types:
Set dts to true in rslib.config.ts to generate the library's type declarations.
Output
Configure the .jsx entry and type declaration entry in package.json, and declare ReactLynx and its type dependencies as peer dependencies:
Testing
You can use Rstest to test ReactLynx components. First, install the dependencies needed for testing:
Use the withRslibConfig function from @rstest/adapter-rslib to reuse your Rslib configuration. See Use Rstest for details.
Also, use the withDefaultConfig function provided by @lynx-js/react to load the ReactLynx test preset, and register the pluginReactLynx plugin from @lynx-js/react-rsbuild-plugin to compile JSX:
Once configured, import APIs such as render, screen, and fireEvent from @lynx-js/react/testing-library to test component rendering and interactions.
See the ReactLynx testing guide for usage details. You can find a complete component testing project in Examples.
Use the component library
Use in an application
In a Lynx application, you can use a ReactLynx component library by importing it as a package or loading it as an External Bundle.
Import from a package
The component library built and published with the configuration above preserves JSX. After installing it in a Lynx application, you can import and use its components directly, with their JSX processed by the application's ReactLynx compiler. For example, use the ScrollList exported by the library:
Load an external bundle
Lynx applications can also load an External Bundle on demand at runtime. Its JSX has already been compiled during the bundle build. When creating the library, you can select the optional External Bundle tool or enable it with --tools external-bundle in the initialization command:
The generated project includes rslib.external-bundle.config.* and a build:external-bundle script. Run the following command to compile the library into dist-external-bundle/<id>.lynx.bundle:
See the Lynx External Bundle guide for loading and configuration details.
Use in a component library
You can use existing shared components in your library and preserve JSX for the application to compile. Distributing the package that provides those components as a dependency is recommended. If you need to publish its code with your library, copy output that is ready to use, or rebuild it when its code, styles, or internal imports need processing.
When publishing dependency code with your library by building or copying it, consumers still need to install the dependency if your .d.ts files reference its types. Use dts.bundle.bundledPackages to bundle those type declarations as well, for example by setting it to ['reactlynx-scroll-list'].
Distribute as a dependency (recommended)
Declare the library that provides the shared components in dependencies or peerDependencies. Rslib marks these dependencies as external by default, preserving their package imports.
When consumers install your library, their package manager installs or reuses packages according to the declared dependencies. The application build then loads these libraries through their package imports and compiles their JSX together.
Rebuild dependency output
If you need to compile the dependency's code or styles, or change its internal imports, use Rslib to build your library and the dependency separately, and use output.externals to rewrite imports.
Consider a component library that includes a scroll list adapted from reactlynx-scroll-list and other components you write. The configuration has three builds, each identified by an id:
components: builds the other components you write in bundleless mode, handling component code that needs to preserve JSX.bundled-components: bundles the scroll list entry and the local TS/JS modules it imports, which can adjust exports or include other TS/JS logic. It usesoutput.externalsto reference the dependency output.vendor: rebuilds the output ofreactlynx-scroll-list, preserving JSX and emitting files todist/vendor/reactlynx-scroll-list.
In this example, only src/scroll-list/index.ts imports reactlynx-scroll-list. Other components reference this entry through local imports:
Adjust outBase and the entry to match the dependency's actual output, including the code, styles, and static assets to process:
The top-level output.filename setting gives all builds a consistent .jsx extension for their code output. The generated dist/scroll-list/index.jsx imports dist/vendor/reactlynx-scroll-list/index.jsx, so include the entire dist directory when publishing your package.
If reactlynx-scroll-list imports other component libraries that also need to be distributed with your package, add builds for those packages. In the vendor build, use output.externals to rewrite their package imports to the paths of their output files.
Copy dependency output directly
If the dependency's output is ready to use and its internal imports need no changes, copy the complete output with output.copy.
The following configuration builds the library source in bundleless mode to preserve JSX and copies the dependency's output. As above, only src/scroll-list/index.ts imports the dependency, and the path in output.externals is relative to the generated dist/scroll-list/index.jsx:
