remix-run/react-router · critical · Error
The React Router Vite plugin requires the use of a Vite conf
Error message
The React Router Vite plugin requires the use of a Vite config file
What it means
Thrown in the `configResolved` hook when the React Router plugin bootstraps its child compiler. To give the child compiler independent plugin state, React Router reloads the user's config via `vite.loadConfigFromFile` using `viteConfig.configFile`. If `configFile` is falsy — meaning Vite was driven purely by inline options or auto-discovery without recording a file — React Router cannot create an isolated plugin set and aborts.
Source
Thrown at packages/react-router-dev/vite/plugin.ts:1429
};
}
},
async configResolved(resolvedViteConfig) {
await initEsModuleLexer;
viteConfig = resolvedViteConfig;
invariant(viteConfig);
// We load the same Vite config file again for the child compiler so
// that both parent and child compiler's plugins have independent state.
// If we re-used the `viteUserConfig.plugins` array for the child
// compiler, it could lead to mutating shared state between plugin
// instances in unexpected ways, e.g. during `vite build` the
// `configResolved` plugin hook would be called with `command = "build"`
// by parent and then `command = "serve"` by child, which some plugins
// may respond to by updating state referenced by the parent.
if (!viteConfig.configFile) {
throw new Error(
"The React Router Vite plugin requires the use of a Vite config file",
);
}
let vite = getVite();
let childCompilerConfigFile = await vite.loadConfigFromFile(
{
command: viteConfig.command,
mode: viteConfig.mode,
},
viteConfig.configFile,
);
invariant(
childCompilerConfigFile,
"Vite config file was unable to be resolved for React Router child compiler",
);View on GitHub (pinned to 1fd704a7da)
Solutions
- Create a `vite.config.ts` at the project root that registers `reactRouter()`.
- If using `--config`, ensure the path resolves to an existing file.
- Avoid `configFile: false` when programmatically building with the React Router plugin.
- Run from the package directory that owns the `vite.config.ts`.
Example fix
// before: programmatic build with no config file
await createServer({ configFile: false, plugins: [reactRouter()] });
// after: ship a real vite.config.ts and let Vite load it
// vite.config.ts
import { reactRouter } from "@react-router/dev";
export default defineConfig({ plugins: [reactRouter()] }); Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from "node:fs";
const ensureConfigFile = (p = "./vite.config.ts") => {
if (!existsSync(p)) throw new Error(`Missing Vite config file: ${p}`);
}; Prevention
- Always run React Router against a real `vite.config.ts` on disk.
- Never pass `configFile: false` programmatically when using the React Router plugin.
- Pin a startup self-check that the config file exists before invoking the CLI.
When it happens
Trigger: Running the React Router plugin against a Vite invocation that has no `vite.config.{ts,js,mjs}` on disk (e.g. `vite build` with `--config` pointing at nothing, or a programmatic `createServer({ configFile: false })`); a config file that failed to load and silently left `configFile` undefined; a monorepo where the wrong package's directory is the CWD.
Common situations: Programmatically invoking Vite from a script with `configFile: false`; running tools that wrap Vite (Storybook, custom SSR harnesses) without a real config file; an empty `.vite/config` after a botched setup.
Related errors
- React Router Vite plugin not found in Vite config
- React Router presets must have a `name` property defined.
- Could not find package.json in ${rootDirectory} or any of it
- Unable to define routes with duplicate route id: "${id}"
- Custom Vite manifest paths are not supported
AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12).
Data as JSON: /api/errors/29ccba274cce8b54.
Report an issue: GitHub.