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.
TL;DR#
TypeError: crypto.hash is not a function inside Vite's Node-side getHash means the running Node executable lacks the hashing function Vite calls. Move to a maintained Node LTS release that satisfies your installed Vite version, then stop and restart Vite in that environment. Check the executable as well as its version: upgrading Node in one terminal does not replace the runtime of a running server, a container or an IDE task.
The original Vite issue reported this failure after scaffolding a React TypeScript project on Windows with Vite 7.0.0 and Node 20.9.0. The dependency installation completed, but starting the dev server failed:
TypeError: crypto.hash is not a functionThe useful part of the stack is the path into Vite's own dependency optimiser: getHash, getLockfileHash and getDepHash. If your stack instead points into application code or a different library, first identify which object that code calls crypto; the diagnosis below is specifically for Vite importing Node's built-in crypto module.
Why Vite can install and still fail at startup#
The Vite 7 hashing implementation imports node:crypto and calls crypto.hash directly. The dependency optimiser source hashes lockfile and configuration inputs to track its dependency cache. That is why the crash can happen before a page opens, even in a tiny project with no application-level cryptography.
Node's crypto API history records that the function was added in Node 20.12.0 and 21.7.0. Older runtimes do not gain that built-in API when you install a newer Vite package. The missing property is not a corrupt browser cache, and adding a browser crypto polyfill cannot supply it to the separate Node process running Vite.
There are two different version questions: whether that function exists, and whether the whole toolchain supports your runtime. Vite 7's package manifest declares this Node engine range:
{
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
}The package's minimum is higher than the first release containing the hashing function. Upgrading only far enough to make the function appear can remove this exception while leaving an unsupported Vite/runtime pairing. Follow the package contract, including any stricter requirements from your framework template or plugins.
For a current reference, npm served Vite 8.3.5 on 2 November 2026, and its published package metadata declares the same range. Its tagged hashing implementation still calls the same Node API. The current Vite guide also warns that some templates need a higher Node version. Treat the range as a compatibility floor, not a recommendation to install an old runtime: the Node release table now lists Node 20 and 21 as end-of-life, while 22, 24 and 26 are LTS lines. A maintained LTS release satisfying your project's dependencies is the appropriate target.
Fix the executable that actually launches Vite#
1. Inspect the project environment#
Run this from the project directory in the terminal, container or build job that fails:
node -e "console.log(process.version); console.log(process.execPath); console.log(typeof require('node:crypto').hash)"It prints the probe's runtime version, executable path and whether the required property is a function. Node documents process.execPath as the absolute path of the executable that started that process. Record the path; two installations can have different versions while both answer to the command node in different environments.
Next, inspect the locally installed Vite contract instead of assuming the version used by the project matches a globally installed CLI:
node -e "const p=require('./node_modules/vite/package.json'); console.log(p.version); console.log(p.engines.node)"An undefined result for the hashing function explains this exception. A function result proves only that this probe has the API; it does not prove a server started earlier uses the same executable. Nor does it override the engine range printed by the second command.
2. Select a maintained runtime and start a fresh process#
Use your existing Node version manager or the official Node installer to select a supported LTS release. Stop the failed Vite invocation, reopen the terminal if the installation changed executable resolution, and repeat the diagnostics. Restart any IDE task that owns the dev server. A newly opened external terminal does not update an IDE's existing environment or a process that is already running.
For an npm-style installation with the local Vite binary at its normal location, this command makes the selected shell Node execute Vite directly:
node ./node_modules/vite/bin/vite.jsThat is useful when the normal script appears to use a different runtime. It bypasses a package-manager launcher while keeping the local Vite installation. If the ordinary script also runs other setup commands, restore that normal workflow after finding and correcting its runtime selection; do not silently discard those commands.
If your existing Vite configuration is reached before the failure, temporarily add this diagnostic alongside its existing imports and configuration:
import crypto from 'node:crypto';
console.log('Vite runtime:', process.version, process.execPath);
console.log('Vite crypto.hash:', typeof crypto.hash);This output comes from the process loading the configuration. It is stronger evidence than checking a different terminal. Remove the diagnostic after verification, and preserve the configuration's existing export.
3. Align Docker and CI separately#
A container uses its image's Node executable. A host upgrade leaves that image unchanged. Update the image used by the stage that installs or runs Vite, rebuild it, and recreate the relevant service. In a multistage build, inspect the stage that actually executes the command; changing a final static web-server image does not change the earlier frontend build runtime.
Apply the same reasoning to CI: select Node before dependency installation and before the build, then print the diagnostic in that job. If changing the image exposes a separate failure while globally upgrading npm, use the Docker npm EBADENGINE diagnosis, which distinguishes npm's own engine requirement from the application's dependencies.
Reproduction: the same Vite package under another Node#
The startup failure was reproduced in isolated Alpine Docker containers on 2 November 2026. The historical test used Vite 7.0.0 and Node 21.2.0, an available old runtime without the function. This deliberately tests the missing-API mechanism; it does not claim to recreate the original Windows installation or its pnpm launcher.
The project contained a root HTML entry and a small JavaScript module. Vite's JavaScript API started a dev server, requested its root page, then ran a production build. Before the change, the runtime diagnostics and failure were:
runtime v21.2.0 /usr/local/bin/node
crypto.hash undefined
vite 7.0.0
TypeError: crypto.hash is not a functionOnly the Node image changed for the next run. The project files, installed Vite package and lockfile stayed in place; the test recorded matching lockfile checksums before and after. With Node 24.22.2, the same test reported:
runtime v24.22.2 /usr/local/bin/node
crypto.hash function
vite 7.0.0
GET / 200 contains Runtime check true
RESULT startup and build passedThis is why deleting the lockfile is unnecessary for this particular cause. It would change the dependency graph while leaving the missing built-in function untouched. If a subsequent error identifies a native dependency built for another platform or runtime, handle that dependency separately and reinstall from the existing lockfile where appropriate.
A separate current-version check then installed Vite 8.3.5 and passed the same startup, HTTP response and production-build checks on Node 24.22.2. That is a separate compatibility check, not part of the single-change historical comparison.
Why the OpenSSL workaround does not supply the function#
The older runtime was also tested with the OpenSSL legacy provider enabled. It still reported the same missing-function exception. An OpenSSL provider cannot create a JavaScript method absent from that Node release.
If your actual error is ERR_OSSL_EVP_UNSUPPORTED or digital envelope routines::unsupported, follow the webpack/OpenSSL hashing diagnosis. The Node release notes describing that OpenSSL error concern an available API refusing an algorithm. Matching the exact exception matters: both faults mention crypto and hashing, but changing provider settings does not solve Vite calling a method that does not exist.
Avoid patching Vite's generated dependency files to replace the call. Such an edit can disappear during installation and hides the unsupported runtime instead of checking the rest of the toolchain. A successful patched startup is weaker evidence than running the package on a supported Node release.
Verify the fix through the normal launch path#
After the direct Node launch works, stop it and run the project's usual development command. Confirm that it starts cleanly under the intended runtime and serves the application. Then run the production build through the project's normal script:
npm run buildUse the equivalent build script for the package manager your repository already uses. Successful installation alone is not the verification target: this failure occurred during dev-server initialisation, so exercise that path as well as the build.
If startup now reaches a ready message but the browser cannot find the page, continue with Vite running but localhost not working. It checks the root HTML entry, listening address and printed port. If the exception instead changes to an ESM-only Tailwind plugin/configuration failure, the Tailwind Vite config diagnosis explains that distinct module-format problem. Once the normal launcher and build both use the intended Node executable, retain the lockfile and record that runtime selection in the development and CI setup so the next terminal or deployment starts the same toolchain.
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.
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 Vite 'global is not defined': shim or move fs code
Why each define line only reveals the next error with fs-extra (reproduced on Vite 2.9.5), which shim works for Buffer-based libraries on Vite 2 and 8, and how to type it.
Fix Vite 'Top-level await is not available' build error
Why vite dev works but vite build fails on a top-level await, which setting fixes the build and which one only fixes dev, reproduced on Vite 2.9, 5.4, 7.3 and 8.3.
Fix: No loader is configured for ".node" files (Vite)
Trace the import that brings a native addon into the dev scan, and distinguish the tested Vite 4 behaviour from newer bundlers.


