remix-run/react-router · critical · Error

React Router Vite plugin not found in Vite config

Error message

React Router Vite plugin not found in Vite config

What it means

Thrown from the `react-router:cli-config` plugin's `configResolved` hook inside `build.ts`. After Vite resolves the merged config, the React Router CLI build scans `config.plugins` for an entry whose `name` is `react-router` or `react-router/rsc`. If none is present, the CLI cannot drive a Framework Mode build and aborts. This is a startup invariant: the `react-router` Vite plugin must be the one registered in the user's `vite.config.ts`, not just installed in `node_modules`.

Source

Thrown at packages/react-router-dev/vite/build.ts:74

              },
            };
          }
          if (sourcemapServer && name !== "client") {
            return {
              build: {
                sourcemap: sourcemapServer,
              },
            };
          }
        },
        configResolved(config) {
          let hasReactRouterPlugin = config.plugins.find(
            (plugin) =>
              plugin.name === "react-router" ||
              plugin.name === "react-router/rsc",
          );
          if (!hasReactRouterPlugin) {
            throw new Error(
              "React Router Vite plugin not found in Vite config",
            );
          }
        },
      },
    ],
  });
  await builder.buildApp();
}

View on GitHub (pinned to 1fd704a7da)

Solutions

  1. Open `vite.config.ts` and confirm `reactRouter()` is in the `plugins` array, e.g. `plugins: [reactRouter()]`.
  2. Ensure the import is `import { reactRouter } from "@react-router/dev";` (Framework Mode) and that `@react-router/dev` is a real dependency.
  3. If using a custom config path, pass it explicitly: `react-router build --config path/to/vite.config.ts`.
  4. For RSC, use the RSC preset so the plugin registers as `react-router/rsc` rather than an arbitrary name.
  5. Print `config.plugins.map(p => p.name)` in a throwaway `configResolved` hook to confirm what Vite actually merged.

Example fix

// before
import { defineConfig } from "vite";
export default defineConfig({ plugins: [] });
// after
import { reactRouter } from "@react-router/dev";
export default defineConfig({
  plugins: [reactRouter()],
});
Defensive patterns

Strategy: validation

Validate before calling

// Before calling react-router build, sanity-check the resolved config
import { resolveConfig } from "vite";
const cfg = await resolveConfig({ configFile: "./vite.config.ts" }, "build");
const ok = cfg.plugins.some(p => p.name === "react-router" || p.name === "react-router/rsc");
if (!ok) throw new Error("reactRouter() not registered in vite.config.ts");

Type guard

const hasReactRouterPlugin = (plugins: { name: string }[]): boolean =>
  plugins.some(p => p.name === "react-router" || p.name === "react-router/rsc");

Prevention

When it happens

Trigger: Calling `react-router build` (or `vite build` with the React Router CLI) against a `vite.config.ts` that does not spread `...reactRouter()` into the `plugins` array; or a config file at a non-default path that the CLI is not pointed at via `--config`; or only installing `@react-router/dev` as a dependency without actually invoking its default-export plugin in the config.

Common situations: New Framework Mode projects scaffolded without the plugin line; migrating a Declarative/Data-mode app to Framework Mode and forgetting to add `reactRouter()` to `plugins`; pointing the CLI at the wrong config via `--config`; an RSC project that registers `reactRouterRSC` under a different alias that lacks the `react-router/rsc` name.

Related errors


AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12). Data as JSON: /api/errors/5e3d2ce780ac1ff5. Report an issue: GitHub.