close
  • English
  • Solid

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

    Create Solid project

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

    npm
    yarn
    pnpm
    bun
    npm create rslib@latest

    Then select Solid when prompted to "Select template".

    Use Rslib in an existing project

    To develop a Solid library, you need to set the target to "web" in rslib.config.ts. This is crucial because Rslib sets the target to "node" by default.

    To compile Solid JSX, you need to register both the @rsbuild/plugin-babel and @rsbuild/plugin-solid plugins. The Solid plugin uses babel-preset-solid to transform JSX into Solid's runtime DOM expressions.

    package.json
    {
      "devDependencies": {
        "@rsbuild/plugin-babel": "^2.0.0",
        "@rsbuild/plugin-solid": "^1.2.2",
        "solid-js": "^1.9.9"
      },
      "peerDependencies": {
        "solid-js": "^1.8.0"
      }
    }
    rslib.config.ts
    import { pluginBabel } from '@rsbuild/plugin-babel'; 
    import { pluginSolid } from '@rsbuild/plugin-solid'; 
    import { defineConfig } from '@rslib/core';
    
    export default defineConfig({
      lib: [
        {
          bundle: false,
          dts: true,
          plugins: [
            pluginBabel({
              include: /\.(?:jsx|tsx)$/,
            }),
            pluginSolid(),
          ],
        },
      ],
      output: {
        target: 'web',
      },
    });

    Output

    Solid component libraries usually ship two types of outputs:

    • Pre-compiled output: JSX has already been transformed by babel-preset-solid into Solid runtime calls, such as template() and insert(). Application projects that use this component library can import this output directly, without configuring Solid JSX compilation.
    • JSX source output: the library build does not compile Solid JSX. Instead, it preserves the original JSX syntax and exposes it through the "solid" condition name in package.json for the application-side toolchain.

    When an application project that uses this component library can compile Solid JSX (for example, an Rsbuild project with @rsbuild/plugin-solid installed), module resolution will hit the "solid" condition name, read the JSX source output, and recompile it for the application's runtime target: browser apps compile it into client-side DOM rendering code (generate: 'dom'), while SSR frameworks compile it into server-side rendering code (generate: 'ssr'). Application projects without Solid JSX compilation configured fall back to the pre-compiled "import" entry.

    rslib.config.ts
    import { pluginBabel } from '@rsbuild/plugin-babel';
    import { pluginSolid } from '@rsbuild/plugin-solid';
    import { defineConfig } from '@rslib/core';
    
    export default defineConfig({
      lib: [
        {
          // Compile JSX into Solid runtime calls, such as template(), insert(), and delegateEvents().
          bundle: false,
          dts: true,
          plugins: [
            pluginBabel({
              include: /\.(?:jsx|tsx)$/,
            }),
            pluginSolid(),
          ],
        },
        {
          // Preserve JSX syntax for the "solid" condition name.
          bundle: false,
          output: {
            filename: {
              js: '[name].jsx',
            },
          },
          tools: {
            swc: {
              detectSyntax: 'auto',
              jsc: {
                transform: {
                  react: {
                    // Keep JSX syntax in the output.
                    runtime: 'preserve',
                  },
                },
              },
            },
            rspack: {
              module: {
                parser: {
                  javascript: {
                    // Allow Rspack to parse preserved JSX.
                    jsx: true,
                  },
                },
              },
            },
          },
        },
      ],
      output: {
        target: 'web',
      },
    });

    Then configure the "exports" field in package.json:

    package.json
    {
      "exports": {
        ".": {
          "solid": "./dist/index.jsx",
          "types": "./dist/index.d.ts",
          "import": "./dist/index.js"
        }
      }
    }

    TypeScript

    For Solid projects using TypeScript, set "jsx": "preserve" and "jsxImportSource": "solid-js" in your tsconfig.json:

    tsconfig.json
    {
      "compilerOptions": {
        "jsx": "preserve",
        "jsxImportSource": "solid-js"
      }
    }

    SSR

    Most Solid component libraries do not publish a separate SSR build by default. Instead, downstream frameworks resolve the "solid" condition name, get the preserved JSX output, and compile it for their own target.

    If you intentionally need a pre-compiled SSR output, configure pluginSolid with the solid.generate option set to 'ssr':

    rslib.config.ts
    export default defineConfig({
      lib: [
        // ... existing compiled and source entries
        {
          id: 'server',
          bundle: false,
          output: {
            distPath: {
              root: './dist/server',
            },
          },
          plugins: [
            pluginBabel({
              include: /\.(?:jsx|tsx)$/,
            }),
            pluginSolid({
              solid: {
                generate: 'ssr',
                hydratable: true,
              },
            }),
          ],
        },
      ],
    });