close
  • English
  • Migrating from Rspress 1.x

    This document will help you migrate from Rspress 1.x to Rspress V2. We recommend using the "Copy as Markdown" feature to pass this document to an LLM for automated migration assistance.

    Quick migration checklist

    • Node.js ^20.19.0 || >=22.12.0
    • Dependencies: rspress@rspress/core, remove @rspress/shared
    • Import paths: rspress/runtime@rspress/core/runtime, rspress/theme@rspress/core/theme
    • Custom themes: Change default exports to named exports, use @rspress/core/theme-original
    • Top-level navigation: _meta.json_nav.json (top-level only)
    • Code highlighting: Prism → Shiki, line highlight syntax {1,3-4} requires transformer config
    • builderPlugins: Move to builderConfig.plugins
    • Sass/Less: Manually install @rsbuild/plugin-sass or @rsbuild/plugin-less
    • External code blocks: <code src="..." />```tsx file="..."
    • markdown.mdxRs: Remove the markdown.mdxRs option (no longer supported)
    • themeConfig.locales: Remove outlineTitle and other text configs, use i18nSource instead

    [Important] Node.js and upstream dependency requirements

    Node.js Version

    Rspress V2 no longer supports Node.js 16 and 18. Please upgrade to Node.js ^20.19.0 || >=22.12.0. Node.js 22 LTS is recommended.

    Upstream dependency versions

    DependencyAllowed RangeDefaultNotes
    react^18.0.0 || ^19.0.019React 17 is no longer supported
    react-dom^18.0.0 || ^19.0.019Keeps in sync with react version
    react-router-dom^6.0.0 || ^7.0.07Uses project version if already installed
    unified^11.0.011Custom remark/rehype plugins must be compatible
    Tip

    If react, react-dom, or react-router-dom is already installed in your project, Rspress will use the project's version instead of the built-in default version.

    [Important] Package name and import path changes

    Rspress V2 consolidates multiple packages into @rspress/core. The original rspress package is no longer used.

    • before:
    package.json
    {
      "dependencies": {
        "rspress": "^1.x",
        "@rspress/shared": "^1.x"
      }
    }
    • after:
    package.json
    {
      "dependencies": {
        "@rspress/core": "^2.0.0"
      }
    }

    If you developed an Rspress plugin, change the plugin's peerDependencies from rspress to @rspress/core:

    package.json
    {
      "peerDependencies": {
        "@rspress/core": "^2.0.0"
      }
    }

    Import path changes

    Old PathNew Path
    rspress / rspress/config@rspress/core
    rspress/runtime@rspress/core/runtime
    rspress/themeUse @rspress/core/theme in docs directory
    @rspress/theme-defaultUse @rspress/core/theme-original in theme directory

    It's recommended to use a global find-and-replace to update import paths.

    Example:

    • before:
    import { usePageData, useDark } from 'rspress/runtime';
    import type { RspressPlugin } from 'rspress';
    • after:
    import { usePageData, useDark } from '@rspress/core/runtime';
    import type { RspressPlugin } from '@rspress/core';

    Removed standalone packages

    The following packages are now built into @rspress/core. If upgrading from 1.x, please refer to the import path changes table above to update your import paths:

    • rspress - Renamed to @rspress/core
    • @rspress/runtime - Runtime is built-in
    • @rspress/theme-default - Default theme is built-in
    • @rspress/plugin-shiki - Shiki code highlighting is now default
    • @rspress/plugin-auto-nav-sidebar - Navigation sidebar is built-in
    • @rspress/plugin-container-syntax - Container syntax is built-in
    • @rspress/plugin-last-updated - Last updated time is built-in
    • @rspress/plugin-medium-zoom - Image zoom is built-in

    [Important] Custom theme ESM export changes

    Custom themes no longer use default exports. Use named exports instead.

    • before:
    theme/index.tsx
    import Theme from 'rspress/theme';
    
    const Layout = () => <Theme.Layout beforeNavTitle={<div>content</div>} />;
    
    export default { ...Theme, Layout };
    
    export * from 'rspress/theme';
    • after:
    theme/index.tsx
    import { Layout as BasicLayout } from '@rspress/core/theme-original';
    
    const Layout = () => <BasicLayout beforeNavTitle={<div>content</div>} />;
    
    export { Layout };
    
    export * from '@rspress/core/theme-original';

    Theme import paths

    ContextImport PathDescription
    theme folder@rspress/core/theme-originalUse when customizing theme, get original theme components
    docs directory@rspress/core/theme or @themeUse theme components in docs, supports theme override

    Using theme components in MDX files within the docs directory:

    docs/guide/index.mdx
    import { PackageManagerTabs } from '@rspress/core/theme';
    // Or use alias
    import { PackageManagerTabs } from '@theme';

    If using the @theme alias, add path mapping in tsconfig.json for type hints:

    tsconfig.json
    {
      "compilerOptions": {
        "paths": {
          "@theme": ["./theme/index.tsx"]
        }
      }
    }
    Tip

    If you encounter errors about missing exports from @theme or @rspress/core/theme, it's likely because you didn't use @rspress/core/theme-original when overriding the theme in the theme folder, causing a circular reference:

    × ESModulesLinkingError: export 'SvgWrapper' (imported as 'SvgWrapper') was not found in '@theme' (possible exports: HomeLayout, Layout, Search, Tag, getCustomMDXComponent)
    
    × ESModulesLinkingError: export 'Banner' (imported as 'Banner') was not found in '@rspress/core/theme' (possible exports: HomeLayout, Layout, Search, Tag, getCustomMDXComponent)

    Make sure to use @rspress/core/theme-original in the theme folder and correctly export all components.

    [Important] Shiki code highlighting replaces prism

    Rspress V2 uses Shiki v3 for code highlighting by default. Prism has been removed.

    For the list of languages supported by Shiki, see Shiki Languages. For more Shiki usage, see the Code Blocks documentation.

    Configuration migration

    • before:

    Configure language aliases via highlightLanguages:

    rspress.config.ts
    import { defineConfig } from 'rspress/config';
    
    export default defineConfig({
      markdown: {
        highlightLanguages: [['ejs', 'javascript']],
      },
    });
    • after:

    Configure langAlias and other Shiki options via markdown.shiki:

    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    
    export default defineConfig({
      markdown: {
        shiki: {
          langAlias: {
            ejs: 'javascript',
          },
        },
      },
    });

    Line highlighting syntax changes

    V2 no longer includes the {1,3-4} meta line highlighting syntax by default. Choose from the following options based on your needs:

    • Notation Line Highlight: Uses // [!code highlight] comment syntax, requires transformerNotationHighlight configuration
    • Meta Line Highlight: Compatible with legacy {1,3-4} syntax, requires transformerCompatibleMetaHighlight configuration

    To maintain compatibility with V1's meta line highlighting syntax, add the following configuration:

    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    import { transformerCompatibleMetaHighlight } from '@rspress/core/shiki-transformers';
    
    export default defineConfig({
      markdown: {
        shiki: {
          transformers: [transformerCompatibleMetaHighlight()],
        },
      },
    });

    [Important] Top-level Navigation file renamed

    Rspress V2 separates nav and sidebar configuration. The top-level _meta.json needs to be renamed to _nav.json, while inner files remain unchanged.

    • before:
    docs/
    ├── en/
    │   ├── _meta.json        # Top-level navigation
    │   └── guide/
    │       └── _meta.json    # Inner sidebar
    • after:
    docs/
    ├── en/
    │   ├── _nav.json         # Top-level navigation (renamed)
    │   └── guide/
    │       └── _meta.json    # Inner sidebar (unchanged)

    [Important] SSG strict mode by default

    SSG is now in strict mode by default. On failure, the build exits immediately instead of falling back to CSR. The ssg.strict configuration has been removed.

    To skip SSG, set ssg: false:

    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    
    export default defineConfig({
      ssg: false,
    });

    [Important] Features enabled by default

    The following features are enabled by default in V2:

    FeatureDescription
    markdown.link.checkDeadLinksDead link checking, fix broken links based on logs
    search.codeBlocksSearch results include code blocks
    dev.lazyCompilationLazy compilation for faster dev startup
    performance.buildCachePersistent cache for faster builds
    Tip

    If you encounter dead link errors, try to fix the broken links rather than disabling the markdown.link.checkDeadLinks feature.

    To disable lazy compilation:

    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    
    export default defineConfig({
      builderConfig: {
        dev: {
          lazyCompilation: false,
        },
      },
    });

    base configuration reimplemented

    The base configuration is now implemented using react-router's basename.

    Key changes:

    • useLocation().pathname no longer includes the base prefix
    • Use Link / useNavigate for navigation instead of directly manipulating window.location

    When cleanUrls: true, generated links no longer include the /index suffix.

    • before: /guide/index
    • after: /guide/

    builderPlugins configuration removed

    builderPlugins has been removed. Please migrate to builderConfig.plugins.

    • before:
    rspress.config.ts
    import { defineConfig } from 'rspress/config';
    
    export default defineConfig({
      builderPlugins: [pluginFoo()],
    });
    • after:
    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    
    export default defineConfig({
      builderConfig: {
        plugins: [pluginFoo()],
      },
    });

    markdown.mdxRs option removed

    The markdown.mdxRs option has been removed in V2. Rspress no longer uses the Rust-based MDX parser (@rspress/mdx-rs). Please remove the markdown.mdxRs option from your configuration.

    Leaving this option in your configuration will cause TypeScript type checking errors, but it does not affect runtime behavior.

    • before:
    rspress.config.ts
    import { defineConfig } from 'rspress/config';
    
    export default defineConfig({
      markdown: {
        mdxRs: false,
        remarkPlugins: [plugin1, plugin2],
      },
    });
    • after:
    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    
    export default defineConfig({
      markdown: {
        // mdxRs option removed, no replacement needed
        remarkPlugins: [plugin1, plugin2],
      },
    });

    Sass/Less Requires manual installation

    Built-in Sass/Less plugins have been removed. Install them manually if needed:

    # Sass
    npm add @rsbuild/plugin-sass -D
    
    # Less
    npm add @rsbuild/plugin-less -D

    Then register in configuration:

    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    import { pluginSass } from '@rsbuild/plugin-sass';
    
    export default defineConfig({
      builderConfig: {
        plugins: [pluginSass()],
      },
    });

    External code block syntax changed

    External code block syntax has changed:

    • before:
    <code src="./example.tsx" />
    • after:
    ```tsx file="./example.tsx"
    
    ```

    Relative links no longer require the ./ prefix. The following two syntaxes are now equivalent:

    [subfolder](subfolder)
    [subfolder](./subfolder)

    MDX file route exclusion

    Files starting with underscore _ are automatically excluded from routing, suitable for MDX fragments and React components.

    docs/
    ├── guide/
    │   ├── _components.tsx  # Will not generate route
    │   └── index.mdx

    Theme style changes

    Tailwind class name prefix

    Built-in theme class names now have a Tailwind prefix to avoid conflicts. If you rely on classes like dark:hidden, configure Tailwind/UnoCSS in your project.

    Native HTML tag styling

    Native HTML tags now have document styling by default. To isolate styling, add the .rp-not-doc class:

    <div class="rp-not-doc">
      <!-- Not affected by document styles -->
    </div>

    Built-in Multilingual text

    The default theme now includes built-in multilingual translation text with tree-shaking support based on your project's configured languages.

    Key changes:

    • If your documentation only includes en and zh, only those languages will be bundled
    • For languages not supported by Rspress, it automatically falls back to en
    • In most cases, you don't need to manually configure i18n text

    The following themeConfig.locales text configurations have been removed. Please delete related configurations:

    • outlineTitle

    • lastUpdatedText

    • editLink.text

    • prevPageText

    • nextPageText

    • sourceCodeText

    • searchPlaceholderText

    • searchNoResultsText

    • searchSuggestedQueryText

    • overview.filterNameText

    • overview.filterPlaceholderText

    • overview.filterNoResultText

    • before:

    rspress.config.ts
    import { defineConfig } from 'rspress/config';
    
    export default defineConfig({
      themeConfig: {
        locales: [
          {
            lang: 'en',
            label: 'English',
            outlineTitle: 'ON THIS PAGE',
          },
          {
            lang: 'zh',
            label: '中文',
            outlineTitle: '目录',
          },
        ],
      },
    });
    • after:
    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    
    export default defineConfig({
      locales: [
        {
          lang: 'en',
          label: 'English',
        },
        {
          lang: 'zh',
          label: '中文',
        },
      ],
      // Only use i18nSource when you want to modify built-in text
      i18nSource: {
        outlineTitle: {
          zh: '大纲',
          en: 'On This Page',
        },
      },
    });

    plugin-preview

    @rspress/plugin-preview V2 no longer includes @rsbuild/plugin-less and @rsbuild/plugin-sass as built-in dependencies. If you need Less or Sass support in previews, install the corresponding plugin and configure it via iframeOptions.builderConfig:

    npm
    yarn
    pnpm
    bun
    deno
    npm add @rsbuild/plugin-less -D
    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    import { pluginPreview } from '@rspress/plugin-preview';
    import { pluginLess } from '@rsbuild/plugin-less';
    
    export default defineConfig({
      plugins: [
        pluginPreview({
          iframeOptions: {
            builderConfig: {
              plugins: [pluginLess()],
            },
          },
        }),
      ],
    });

    For more migration details, see plugin-preview migration guide.

    Resources