Fix Vite "Cannot find package vite" in vite.config.ts
Why vite vanishes from node_modules after a clean install, reproduced on npm 9.5.0 and Node 18 with a global vite install, plus the extra step the fix needs to outlast the next npm install.
TL;DR#
npm create vite@latest puts vite itself, its framework plugin and TypeScript under
devDependencies — only react and react-dom land in dependencies. If npm install runs
while the NODE_ENV environment variable is already production, or with --omit=dev (or the
deprecated --production flag), npm skips devDependencies on purpose: vite is resolved into
the lockfile but never written to node_modules, so the dev server and the build both fail. Run
npm install --include=dev to get it back, then find and remove whatever set NODE_ENV=production
in the first place — otherwise the next plain npm install repeats the exact same failure.
A developer hit this with the default React + TypeScript template and reported the exact output below:
> vite-react@0.0.0 dev
> vite
failed to load config from [my-path]\vite-project\vite-react\vite.config.ts
error when starting dev server:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'vite' imported from [my-path]\vite-project\vite-react\vite.config.ts.timestamp-1677228345613.mjs
at new NodeError (node:internal/errors:399:5)
at packageResolve (node:internal/modules/esm/resolve:889:9)
at moduleResolve (node:internal/modules/esm/resolve:938:20)
at defaultResolve (node:internal/modules/esm/resolve:1153:11)
at nextResolve (node:internal/modules/esm/loader:163:28)
at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
at link (node:internal/modules/esm/module_job:76:36)(reported on Node v18.14.2, npm 9.5.0, vite/4.1.1. The same report says a plain Vanilla +
TypeScript project on the same machine worked, even though its package.json also lists vite
only under devDependencies — the report does not say whether that install kept its
devDependencies or avoided this failure some other way; the accepted answer below only
establishes that this project's install dropped them.)
Check your own ERR_MODULE_NOT_FOUND#
Paste the exact error Node.js printed for your own project — this runs in your browser, nothing is sent anywhere.
Runs entirely in your browser — nothing you paste is sent anywhere. Tokens and passwords that appear in paths or URLs are masked in the output.
Optional: package.json, file extension, Node.js version (sharper advice)
If it tells you to run npm ci, add --include=dev to that too while NODE_ENV=production is
set: npm ci reconciles node_modules with the lockfile under the same omit rule as
npm install, so it skips devDependencies for the same reason.
Why it happens#
Run npm create vite@latest today and pick the React + TypeScript template: the generated
package.json still puts vite, @vitejs/plugin-react, typescript and the @types/*
packages under devDependencies, next to react and react-dom in dependencies — the exact
shape of the package.json pasted in the original report,
only with newer version numbers.
npm decides which dependency types to physically write to disk with its omit config. Its
default is not fixed — it depends on the environment the moment npm install runs. From npm's
own source, unchanged in substance from the reporter's npm 9.5.0 to today's npm 12:
define('omit', {
default: process.env.NODE_ENV === 'production' ? ['dev'] : [],
...
description: `
Dependency types to omit from the installation tree on disk.
Note that these dependencies _are_ still resolved and added to the
package-lock.json or npm-shrinkwrap.json file. They are just
not physically installed on disk.
...
If the resulting omit list includes 'dev', then the NODE_ENV
environment variable will be set to 'production' for all lifecycle
scripts.
`,
...
})(condensed: ... marks omitted lines, and the escaped backticks the real source uses around
code names inside its template-literal description are removed here for readability; nothing in
the quoted wording itself is changed. npm/cli
lib/utils/config/definitions.js, tag v9.5.0,
unchanged at the current tag;
documented the same way on npm's own config reference.)
In plain terms: if NODE_ENV is already production when npm install runs — from a stray
environment variable, an .npmrc with production=true or omit=dev, or the explicit
--omit=dev / deprecated --production flag — npm quietly leaves every devDependency out of
node_modules. vite is a devDependency, so it is one of the packages left out, and so is
@vitejs/plugin-react.
The accepted answer on the original report reached the same conclusion from the other direction, after first trying a workaround:
UPDATE, SOLUTION:
`npm install --include=dev`
well not a solution to the root cause but works.
And the actual root cause was:
`npm install` did not install the devDependencies in the automatically generated `package.json` by default...Reproduced: on npm 9.5.0 / Node 18.20.8, installing the reporter's own package.json with
NODE_ENV=production set (so the local devDependencies, vite included, are skipped)
reproduces the same three lines as the report — "failed to load config from …", "error when
starting dev server:", and the Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'vite' imported from …timestamp-*.mjs line, with the container's path and timestamp standing in for
the reporter's — but only once a vite binary exists somewhere else that the shell can still
reach (a global npm install -g vite, in this run). npm run dev runs the project's dev
script, vite, and npm adds the project's own node_modules/.bin to PATH for that script;
when vite is missing there, the shell falls through to the rest of PATH and finds the global
one instead — but only until the local copy exists again: after npm install --include=dev,
the same npm run dev started VITE v4.5.14, the version the project's vite@^4.1.0 resolved
to, not the globally installed 4.1.1 (both logged in repro.log), so the local node_modules
wins once it is there. That global vite starts, and both the dev server's
createServer
and
build
call resolveConfig, which calls loadConfigFromFile —
the same path either way. For an ESM project, loadConfigFromFile
bundles vite.config.ts,
and a source comment calls what follows a hack: "write it to disk, load it with native Node ESM,
then delete the
file" (config.ts#L1065-L1069),
named <file>.timestamp-<epoch>.mjs. That temporary file's import … from "vite" still has to
resolve against the project's node_modules — where the package is still missing — so it
throws ERR_MODULE_NOT_FOUND instead of the plainer sh: vite: not found a project with no
vite anywhere at all would print. The report does not say whether a global Vite was the exact
reason in this case; what it confirms is only that npm install skipped the project's
devDependencies.
Fix#
-
Find out why devDependencies are being skipped, so the fix outlasts this one install. Check the environment variable and the four
.npmrcfiles npm reads — a project file, a per-user file ($HOME/.npmrc), a global file, and npm's own built-in config file:bashecho $NODE_ENV # macOS/Linux/WSL shell npm config list -l | grep -i "omit\|production"powershell$env:NODE_ENV # PowerShell, on the reporter's own OSA
NODE_ENVset through Windows' System Properties → Environment Variables (or an oldsetx NODE_ENV production) persists across every new terminal until it is removed there. A plainexport NODE_ENV=…typed directly into one Linux/macOS shell does not outlive that shell, but the same line sitting in a~/.bashrcor~/.zshrcruns again for every new terminal too, so check those as well before assuming the cause was a one-off. -
Install the missing devDependencies now:
bashnpm install --include=dev--include=devoverrides theomitdefault for this one run, regardless of what set it. Reproduced on npm 9.5.0 with the reporter's ownpackage.json: a plainnpm installwhileNODE_ENV=productionadded 5 packages and leftviteout;npm install --include=devright after added 56 more, includingviteitself. -
Remove the cause, not just the symptom. Unset the stray
NODE_ENV, delete theproduction=trueoromit=devline from whichever.npmrcstep 1 found, or stop passing--omit=dev/ --production. Skip this step and the fix looks like it "stops working" later: a teammate's fresh clone, a CI cache rebuild, or your own nextrm -rf node_modules && npm installreads the exact same leftover config and reproduces the failure from scratch, because a plainnpm installstill honours it. -
In Docker or CI, do not blanket-unset it. A Dockerfile with
ENV NODE_ENV=productionset beforeRUN npm install, or a deploy step that exports the same variable on purpose, is correct for the dependencies a running backend needs — that part should stay. A Vite front end still needs its build step, which needsvite, a devDependency, to run before that backend ever serves anything, so only that one step needsnpm install --include=dev(ornpm ci --include=dev) even in an otherwise production build.
Verify the fix#
With vite back in node_modules, the same project — global vite installed or not — starts
cleanly:
> vite-react@0.0.0 dev
> vite
VITE v4.5.14 ready in 1035 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose(reproduced on Node 18.20.8 / npm 9.5.0 / the reporter's 2023 package.json, 26 October 2026 —
vite@^4.1.0 resolved to 4.5.14, the newest release still satisfying that range.) vite build
loads vite.config.ts the same way vite (dev) does, so a stuck production build is the same
check: confirm vite is a real directory under node_modules, not just listed in
package.json.
If your editor also underlines the @vitejs/plugin-react import in vite.config.ts, check
which case you are in. With devDependencies skipped, @vitejs/plugin-react is missing too —
the same root cause as this page, just reported by the editor instead of node, and fixed by
the same npm install --include=dev. A TS2307 that survives that install, with the dev server
running fine, is a different bug: see
Fix Cannot find module '@vitejs/plugin-react' in Vite
for the tsconfig.node.json resolution case, where the package is already on disk and only the
editor's module resolution is wrong.
One email a month — the latest explained errors
What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.
In Docker, tell this apart from two other Vite failures#
If this project is built inside Docker, a line such as ENV NODE_ENV=production applies to
every instruction that follows it in that build stage — including a RUN npm install placed
after it to build the front end, even when the variable was only meant to describe the final,
deployed image. Two other Vite-in-Docker
failures look superficially similar but need a different fix, so it is worth telling them apart
before assuming this article covers a container error too: a bind
mount that brings a host node_modules built for the wrong OS/CPU into the container fails on
the native esbuild binary, not on a missing vite (see
Fix "esbuild-linux-64" could not be found: Vite in Docker),
and a .dockerignore that excludes index.html fails at the bundler's entry point, with vite
present and working (see
Vite entry module (index.html): fix .dockerignore).
If the error names vite itself and ERR_MODULE_NOT_FOUND or "not found", the devDependency fix
above is the one that applies.
A later failure, unrelated to installation, can show up at build time once npm run dev itself
is fixed. Vite's dev server transpiles TypeScript on the fly and does not check which browsers the result
has to run in; vite build does check, against build.target, and can reject code the dev
server let through silently — your own module's top-level await is one documented case (a
dependency's top-level await is different: Vite's dev pre-bundler checks dependencies too, so
that case can fail in dev as well). If dev
now works but build stops with a different, unrelated-looking error, that is a separate,
already documented failure: see
Fix Vite 'Top-level await is not available' build error.
Further reading: Vite linked React library: fix Invalid hook call.
Frequently Asked Questions
Still stuck? Paste your error.
Paste the error message or stack trace — we check it against every fix and tool on the site.
Continue Reading
Fix Cannot find module @rollup/rollup-win32-x64-msvc
Find out where your node_modules came from, reinstall it for the machine that runs Vite, and avoid the popular fix that breaks Linux CI and Docker builds.
Fix "No license field" when package.json has a license
Read the path in the warning, find the stray package.json above your project, and silence the line without inventing an open-source licence.
Fix Vite: crypto.hash is not a function
Check the Node binary that actually starts Vite, distinguish API availability from the supported version range, and verify the fix without replacing the lockfile.


