Diagnosing Vite.js Hot Module Replacement Failures: Symptoms, Checks, and Fixes
A step‑by‑step diagnostic guide for Vite.js HMR failures: symptoms, cause table, ordered checks, fixes, and when to escalate.
29 Sept 2025, 01:39 UTC

Recognizable condition
You start the Vite dev server, edit a source file, and the browser either does not update, reloads the whole page, or shows a WebSocket error. This indicates that Hot Module Replacement (HMR) is not working as expected.
Useful takeaway
By following a short symptom‑cause table, performing ordered checks, and applying the fix that matches the finding, you can restore HMR without guessing.
Cause / diagnostic table
| Symptom | Likely cause |
|---|---|
| Edits to JS/TS files do not appear; no reload | File watcher ignores the edited directory (e.g., matches node_modules, .git) or lacks OS permission for chokidar. |
| Saving a file triggers a full page reload | Missing or misconfigured plugin for the file type (e.g., .vue without @vitejs/plugin-vue) or plugin order overrides HMR hooks. |
| HMR works for some files but not others, or works intermittently | Plugin version mismatch or plugin order causing HMR hooks to be overridden. |
| Console shows "[vite] HMR connection lost" or WebSocket errors | Proxy, VPN, or corporate firewall blocks the WebSocket to /@vite/client. |
| Editing CSS/SCSS/Less results in full reload instead of style injection | Missing preprocessor plugin (e.g., sass, less) or missing PostCSS config. |
Ordered checks
- Verify the dev server is running
Run
npm run dev(orvite) in the project root. Ensure you have read/write permission on the project directory. - Check the console for HMR logs
Open Chrome DevTools → Console. After saving a file, look for a line like
[vite] HMR updated ./src/main.js. Absence of this line indicates the server did not detect the change. - Inspect the WebSocket connection
In DevTools → Network, filter for WS. Confirm a connection to
http://localhost:5173/@vite/client(or your Vite port) with status 101 and that it stays open while you edit. - Review vite.config.js
Look for missing plugins, incorrect
server.watchignores, or plugin order that could override HMR. Example of a problematic config:import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], server: { watch: { // Accidentally ignoring the src folder ignored: ['!**/src/**'] } } })The
ignoredpattern above would prevent Vite from watching any file undersrc. - Confirm required preprocessor plugins
If you edit
.scssfiles, ensuresass(ordart-sass) is installed and listed indevDependencies. Vite will automatically use it, but if missing, it falls back to treating the file as a static asset, causing a full reload. - Test network intermediaries
Temporarily disable any proxy, VPN, or corporate firewall and repeat the edit. If HMR works, the intermediary was blocking the WebSocket.
Fixes tied to findings
- File watcher not tracking
- Remove or correct any
server.watch.ignoredpatterns that match your source files. - Ensure the user running
vitehas read permission on the project directory (no need for elevated privileges).
- Remove or correct any
- Missing/misconfigured plugin
- Install the official plugin for your framework:
npm i -D @vitejs/plugin-vuefor Vue,npm i -D @vitejs/plugin-reactfor React, etc. - Add the plugin to the
pluginsarray invite.config.js. - Check plugin order: plugins that alter the module graph (e.g.,
vite-plugin-svgr) should be placed before framework plugins if they need to run first.
- Install the official plugin for your framework:
- Plugin version mismatch
- Run
npm list @vitejs/plugin-vue(or the relevant plugin) to see installed versions. - Upgrade to the latest compatible version:
npm update @vitejs/plugin-vue. - Consult the plugin’s changelog for breaking changes that affect HMR.
- Run
- WebSocket blocked
- Configure your proxy to allow traffic to
http://localhost:[port]/@vite/client. - If using a corporate VPN, ask network staff to whitelist the Vite dev server port or split‑tunnel the traffic.
- As a quick test, run the dev server on a different port (
vite --port 3000) and see if the issue persists.
- Configure your proxy to allow traffic to
- Missing preprocessor
- Install the required preprocessor:
npm i -D sassfor SCSS,npm i -D lessfor Less,npm i -D stylusfor Stylus. - Ensure you have a valid
postcss.config.jsif you rely on PostCSS plugins (e.g., autoprefixer).
- Install the required preprocessor:
Escalation criteria
If after applying the relevant fix the HMR still does not work:
- Create a minimal reproducible example (clone the repo, remove unrelated dependencies, keep only
vite, the framework plugin, and a singlesrc/main.jsthat imports a component). - Run
vite --debugto get verbose logs; look for lines containingwatch,hmr, orWebSocket. - Share the logs and the minimal
vite.config.jsin the Vite GitHub Discussions or Stack Overflow with the tagvitejsandhmr.
Escalate only after you have verified that the dev server starts without errors, the file watcher is active (you see [vite] dev server running at: in the terminal), and the WebSocket connection is established but no HMR updates are logged.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.