> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# TanStack Start

TanStack Start supports Rsbuild for React and Solid applications. This guide replaces the Vite integration while preserving TanStack Start's managed client and server entries.

Do not apply the generic [build entry](/guide/migration/vite.md#build-entry) migration steps to a TanStack Start application.

## Before you start

Keep your existing `tanstackStart` options, routes, server functions, and application code. This migration changes the build tool; it does not change the TanStack Start application model.

Review your Vite configuration and deployment integration before editing dependencies. Vite plugins cannot run in `rsbuild.config.ts`; migrate each one to an Rsbuild or Rspack equivalent, or remove it only after confirming that it is no longer needed.

## Replace the Vite configuration

### React

Remove Vite and its React plugin, then install the Rsbuild equivalents:


```sh [npm]
npm remove vite @vitejs/plugin-react
```

```sh [yarn]
yarn remove vite @vitejs/plugin-react
```

```sh [pnpm]
pnpm remove vite @vitejs/plugin-react
```

```sh [bun]
bun remove vite @vitejs/plugin-react
```

```sh [deno]
deno remove npm:vite npm:@vitejs/plugin-react
```


```sh [npm]
npm add @rsbuild/core @rsbuild/plugin-react -D
```

```sh [yarn]
yarn add @rsbuild/core @rsbuild/plugin-react -D
```

```sh [pnpm]
pnpm add @rsbuild/core @rsbuild/plugin-react -D
```

```sh [bun]
bun add @rsbuild/core @rsbuild/plugin-react -D
```

```sh [deno]
deno add npm:@rsbuild/core npm:@rsbuild/plugin-react -D
```

If you use `@vitejs/plugin-react-swc`, remove that package instead. Keep `@tanstack/react-start` and `@tanstack/react-router` installed.

Replace `vite.config.ts` with `rsbuild.config.ts`:

```ts title="rsbuild.config.ts"
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { tanstackStart } from '@tanstack/react-start/plugin/rsbuild';

export default defineConfig({
  plugins: [pluginReact(), tanstackStart()],
});
```

This is the minimal configuration used by the [Rsbuild React example](https://github.com/rstackjs/rstack-examples/tree/main/rsbuild/tanstack-start), excluding its optional Tailwind CSS plugin.

### Solid

Remove Vite and its Solid plugin, then install the Rsbuild equivalents:


```sh [npm]
npm remove vite vite-plugin-solid
```

```sh [yarn]
yarn remove vite vite-plugin-solid
```

```sh [pnpm]
pnpm remove vite vite-plugin-solid
```

```sh [bun]
bun remove vite vite-plugin-solid
```

```sh [deno]
deno remove npm:vite npm:vite-plugin-solid
```


```sh [npm]
npm add @rsbuild/core @rsbuild/plugin-babel @rsbuild/plugin-solid -D
```

```sh [yarn]
yarn add @rsbuild/core @rsbuild/plugin-babel @rsbuild/plugin-solid -D
```

```sh [pnpm]
pnpm add @rsbuild/core @rsbuild/plugin-babel @rsbuild/plugin-solid -D
```

```sh [bun]
bun add @rsbuild/core @rsbuild/plugin-babel @rsbuild/plugin-solid -D
```

```sh [deno]
deno add npm:@rsbuild/core npm:@rsbuild/plugin-babel npm:@rsbuild/plugin-solid -D
```

Keep `@tanstack/solid-start` and `@tanstack/solid-router` installed.

Replace `vite.config.ts` with `rsbuild.config.ts`:

```ts title="rsbuild.config.ts"
import { defineConfig } from '@rsbuild/core';
import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginSolid } from '@rsbuild/plugin-solid';
import { tanstackStart } from '@tanstack/solid-start/plugin/rsbuild';

export default defineConfig({
  plugins: [
    pluginBabel({
      include: /\.(?:jsx|tsx)$/,
    }),
    pluginSolid(),
    tanstackStart(),
  ],
});
```

This is the minimal configuration used by the [Rsbuild Solid example](https://github.com/rstackjs/rstack-examples/tree/main/rsbuild/tanstack-start-solid), excluding its optional Tailwind CSS plugin.

## Update scripts

Retain `"type": "module"` in `package.json`, then replace the Vite scripts:

```json title="package.json"
{
  "type": "module",
  "scripts": {
    "dev": "vite dev", // [!code --]
    "build": "vite build", // [!code --]
    "preview": "vite preview", // [!code --]
    "dev": "rsbuild", // [!code ++]
    "build": "rsbuild build", // [!code ++]
    "preview": "rsbuild preview" // [!code ++]
  }
}
```

`rsbuild` without a subcommand starts the dev server. `rsbuild dev` is equivalent.

### Route generation

If the project has a `generate-routes` script that runs `tsr generate`, replace it with `rsbuild build`:

```json title="package.json"
{
  "scripts": {
    "generate-routes": "tsr generate", // [!code --]
    "generate-routes": "rsbuild build" // [!code ++]
  }
}
```

The TanStack Start Rsbuild plugin generates the route tree during the build and adds its required registration to `routeTree.gen.ts`. Running `tsr generate` directly can overwrite that registration.

## Migrate project-specific settings

The configuration above replaces only the TanStack Start and Vite integration. Migrate all other Vite configuration deliberately:

- Use the [Vite config migration reference](/guide/migration/vite.md#config-migration) for aliases, CSS, dev server settings, static assets, and other Vite options.
- Replace each Vite plugin with an Rsbuild or Rspack equivalent. Integrations that expose only a Vite plugin need a separately supported replacement.
- Delete `vite.config.ts` after its settings have been migrated.

### React Compiler

For React applications that use React Compiler through a Babel plugin, configure the built-in Rspack implementation instead:

```ts title="rsbuild.config.ts"
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';

export default defineConfig({
  plugins: [
    pluginReact({
      reactCompiler: true,
    }),
  ],
});
```

If a Babel or Rolldown Babel plugin was used only for React Compiler, remove that plugin and `babel-plugin-react-compiler`. For React 17 or 18 applications, install `react-compiler-runtime` and set the compiler target as described in the [React plugin documentation](/plugins/list/plugin-react.md#reactcompiler).

### TypeScript

Replace Vite's preset types in `tsconfig.json` with Rsbuild's preset types. If your project already defines a `types` array, replace only the Vite entries and retain the other required types:

```json title="tsconfig.json"
{
  "compilerOptions": {
    "types": ["vite/client", "vite-plugin-svgr/client"], // [!code --]
    "types": ["@rsbuild/core/types"] // [!code ++]
  }
}
```

`@rsbuild/plugin-svgr` does not provide a TypeScript declaration for `*.svg?react` imports. If your application uses that query, add a declaration file such as `src/types/svg.d.ts`:

```ts title="src/types/svg.d.ts"
declare module '*.svg?react' {
  import type { FunctionComponent, SVGProps } from 'react';

  const ReactComponent: FunctionComponent<SVGProps<SVGSVGElement>>;
  export default ReactComponent;
}
```

### Environment variables

Rsbuild exposes client environment variables with the `PUBLIC_` prefix. Rename every client variable from `VITE_*` to `PUBLIC_*`, including its definition in `.env` files, CI variables, Docker build arguments, and application code:

```diff
- VITE_API_URL
+ PUBLIC_API_URL
```

Update application code to use direct property access, such as `import.meta.env.PUBLIC_API_URL`. If an environment validator receives the entire `import.meta.env` object, pass it an explicit object containing the required `PUBLIC_` properties.

### Static prerendering and CDN URLs

Keep options passed to `tanstackStart`. For example, static prerendering remains configured through the plugin:

```ts
tanstackStart({
  prerender: {
    enabled: true,
    crawlLinks: true,
  },
});
```

See the [React](https://tanstack.com/start/latest/docs/framework/react/guide/static-prerendering) and [Solid](https://tanstack.com/start/latest/docs/framework/solid/guide/static-prerendering) static prerendering guides for all available options.

For React applications that use CDN asset URLs, configure `transformAssets` in the TanStack Start server entry. This is different from setting an Rsbuild `assetPrefix`:

```ts
const handler = createStartHandler({
  handler: defaultStreamHandler,
  transformAssets: process.env.CDN_ORIGIN || '',
});
```

Use the React server APIs when creating the handler. See [CDN asset URLs](https://tanstack.com/start/latest/docs/framework/react/guide/cdn-asset-urls) for a complete example.

### Paraglide

If you use Paraglide, replace `paraglideVitePlugin` with `paraglideRspackPlugin` and register it in `tools.rspack.plugins`. Keep the existing plugin options and generated output directory.

### Sentry

Replace the Vite adapter's build-time integration with [`@sentry/webpack-plugin`](https://www.npmjs.com/package/@sentry/webpack-plugin). Register it in `tools.rspack.plugins`, enable `hidden-source-map` when uploading source maps, and set `SENTRY_AUTH_TOKEN` and `SENTRY_RELEASE` in CI.

If you use a Sentry tunnel, define a TanStack Start route and limit it to your public DSN:

```ts title="src/routes/monitoring.ts"
import * as Sentry from '@sentry/tanstackstart-react';
import { createFileRoute } from '@tanstack/react-router';

const sentryDsn = import.meta.env.PUBLIC_SENTRY_DSN;

export const Route = createFileRoute('/monitoring')({
  server: Sentry.createSentryTunnelRoute({
    allowedDsns: sentryDsn ? [sentryDsn] : [],
  }),
});
```

Configure the same path with the client SDK's `tunnel` option.

## Migrate tests from Vitest to Rstest

Vitest runs tests through Vite. If you want to remove Vite from the test toolchain, migrate the Vitest configuration and test imports to Rstest before removing `vitest`, `@vitest/coverage-v8`, and Vite-only test plugins.

Install Rstest and its Rsbuild adapter. Add the V8 coverage package when the Vitest configuration uses V8 coverage:


```sh [npm]
npm add @rstest/core @rstest/adapter-rsbuild @rstest/coverage-v8 jsdom -D
```

```sh [yarn]
yarn add @rstest/core @rstest/adapter-rsbuild @rstest/coverage-v8 jsdom -D
```

```sh [pnpm]
pnpm add @rstest/core @rstest/adapter-rsbuild @rstest/coverage-v8 jsdom -D
```

```sh [bun]
bun add @rstest/core @rstest/adapter-rsbuild @rstest/coverage-v8 jsdom -D
```

```sh [deno]
deno add npm:@rstest/core npm:@rstest/adapter-rsbuild npm:@rstest/coverage-v8 npm:jsdom -D
```

Create `rstest.config.ts` and reuse the application configuration:

```ts title="rstest.config.ts"
import { withRsbuildConfig } from '@rstest/adapter-rsbuild';
import { defineConfig } from '@rstest/core';

export default defineConfig({
  extends: withRsbuildConfig(),
  testEnvironment: 'jsdom',
  setupFiles: ['./src/test/setup.ts'],
  coverage: {
    provider: 'v8',
    reporters: ['text', 'html', 'lcov', 'cobertura'],
  },
});
```

Rstest options are top-level fields: for example, move `test.environment` to `testEnvironment`, `test.setupFiles` to `setupFiles`, and `test.coverage` to `coverage`. Rename Vitest's `coverage.reporter` option to `coverage.reporters`.

Replace test API imports:

```ts
import { describe, expect, it } from 'vitest'; // [!code --]
import { describe, expect, it } from '@rstest/core'; // [!code ++]
```

For Testing Library and `@testing-library/jest-dom`, register matchers with Rstest's `expect` in the setup file. Use the Testing Library package for your framework:

```ts title="src/test/setup.ts (React)"
import { cleanup } from '@testing-library/react';
import * as jestDomMatchers from '@testing-library/jest-dom/matchers';
import { afterEach, expect } from '@rstest/core';

expect.extend(jestDomMatchers);
afterEach(cleanup);
```

```ts title="src/test/setup.ts (Solid)"
import * as jestDomMatchers from '@testing-library/jest-dom/matchers';
import { cleanup } from '@testing-library/solid';
import { afterEach, expect } from '@rstest/core';

expect.extend(jestDomMatchers);
afterEach(cleanup);
```

Update scripts to use `rstest`, `rstest --watch`, and `rstest --coverage`. For more configuration mappings, see the [Rstest migration guide](https://rstest.rs/guide/migration/vitest) and the Rsbuild [Testing](/guide/advanced/testing.md) guide.

## Deploy to Node.js or docker

If `nitro/vite` is used only for Node.js or Docker deployment, remove `nitro`. A TanStack Start Rsbuild build emits its own server entry. Install [srvx](https://srvx.h3.dev/) as a production dependency:



```sh [npm]
npm remove nitro
```

```sh [yarn]
yarn remove nitro
```

```sh [pnpm]
pnpm remove nitro
```

```sh [bun]
bun remove nitro
```

```sh [deno]
deno remove npm:nitro
```


```sh [npm]
npm add srvx
```

```sh [yarn]
yarn add srvx
```

```sh [pnpm]
pnpm add srvx
```

```sh [bun]
bun add srvx
```

```sh [deno]
deno add npm:srvx
```

```json title="package.json"
{
  "scripts": {
    "start": "srvx --prod -s ../client dist/server/index.js"
  }
}
```

The production build emits client assets in `dist/client` and the fetch-style server entry in `dist/server/index.js`. If your build emits `dist/server/server.js`, use that path instead.

For Docker, install production dependencies again in the final stage. The `runner` stage starts from a fresh base image: the builder's `node_modules` includes development dependencies and should not be copied to the runtime image.

Use the following `runner` stage in your Dockerfile. It detects the package manager from the project's lockfile and supports npm, Yarn, and pnpm:

```dockerfile title="Dockerfile (runner stage)"
FROM node:24-alpine AS runner
WORKDIR /app
COPY package.json package-lock.json* yarn.lock* pnpm-lock.yaml* .npmrc* ./
RUN corepack enable && \
  if [ -f package-lock.json ]; then \
    npm ci --omit=dev --ignore-scripts; \
  elif [ -f yarn.lock ]; then \
    yarn install --frozen-lockfile --production=true --ignore-scripts; \
  elif [ -f pnpm-lock.yaml ]; then \
    pnpm install --prod --frozen-lockfile --ignore-scripts; \
  else \
    echo "No lockfile found." && exit 1; \
  fi
COPY --from=builder /app/dist ./dist
CMD ["./node_modules/.bin/srvx", "--prod", "-s", "../client", "dist/server/index.js"]
```

Configure the preceding build stages according to the TanStack Start [React](https://tanstack.com/start/latest/docs/framework/react/guide/hosting) or [Solid](https://tanstack.com/start/latest/docs/framework/solid/guide/hosting) deployment guide.

For deployment targets other than Node.js or Docker, Vite-specific deployment integrations cannot be used with Rsbuild. Use a supported non-Vite adapter, or retain the Vite integration. See the [React hosting guide](https://tanstack.com/start/latest/docs/framework/react/guide/hosting) and [Solid hosting guide](https://tanstack.com/start/latest/docs/framework/solid/guide/hosting).
