← Back to list

What is HMR? (Hot Module Replacement)

Er Anil Kumar — Angular Advocate

Anil Kumar · 2026-01-24 17:16 · 0 claps · 3.3 min read
#angular #hmr #webpack #vitejs
Open on Medium ↗
Wiki topics: 🌐 · Web Development

What is HMR? (Hot Module Replacement)

Er Anil Kumar — Angular Advocate

Hot Module Replacement (HMR) updates just the changed modules in a running application without doing a full page reload. The dev server patches your app in the browser, preserving runtime state when possible — so forms don’t reset, scroll doesn’t jump, and you stay on the same route. Result: faster feedback loop and fewer context switches.

How HMR Works (Mental Model)

  1. You edit a file.
  2. The bundler (Webpack, Vite/Rollup, esbuild) recompiles only what changed.
  3. The dev server sends a hot update over WebSocket/EventSource.
  4. The runtime in the browser accepts the new module and swaps it in.
  5. If a module (or one of its parents) can’t accept the update, the server falls back to a full reload.

HMR is a dev-time feature only — it should never ship to production.

Benefits

  • State preservation: often keeps component/service state during edits.
  • Speed: avoids full rebuilds and reloads.
  • Focus: no losing your place (route, scroll, inputs).
  • Granular errors: you see exactly which module failed to hot‑apply.

Angular Today: Two Worlds

A) Angular (Webpack‑based CLI, v2–v16 and many legacy apps)

HMR is supported via the Angular CLI dev server (Webpack under the hood).

Add HMR in seconds

Shell

one-off run with HMR

ng serve — hmr

or using a configured configuration

ng serve -c hmr

Show more lines

angular.json (optional configuration)

JSON

{

“projects”: {

“app”: {

“architect”: {

“serve”: {

“configurations”: {

“hmr”: {

“hmr”: true

}

}

}

}

}

}

}

No app code changes required for the basics. The CLI wires Webpack HMR runtime automatically.

What gets preserved?

  • Most component trees refresh in place.
  • Global singletons (services providedIn:'root') retain JS state in memory when the module boundary accepts updates.
  • If the update touches bootstrap code or non‑accepting parents, the dev server triggers a full reload.

Typical “why did it reload?” reasons

  • Changing polyfills, environment bootstrap, or main.ts root wiring.
  • Updating module that doesn’t accept hot updates up the chain.
  • Changing CSS usually works instantly; changing global styles may trigger broader updates.

B) Angular with Vite (v17+ default, or @angular-devkit → Vite migration)

Angular moved to a Vite-powered dev server by default (and uses esbuild/rollup under the hood). Vite ships best‑in‑class HMR.

Run dev server (HMR is on by default)

Shell

ng serve

or

npm start

``

No flags needed — HMR is part of Vite’s dev experience.

Component‑level ergonomics

  • Template/CSS edits are near‑instant.
  • TS logic updates hot‑swap where safe.
  • If a boundary can’t accept, Vite falls back to full reload.

If you see unexpected reloads, check for side effects executed at import time; move them into functions/hooks so Vite can accept modules cleanly.

Framework‑Agnostic Examples

Webpack accept API (conceptual)

JavaScript

if (import.meta.webpackHot) {

import.meta.webpackHot.accept((err) => {

if (err) console.error(‘HMR accept failed:’, err);

});

}

Show more lines

Vite HMR API (conceptual)

JavaScript

if (import.meta.hot) {

import.meta.hot.accept(() => {

// handle update, re-register handlers, etc.

});

}

``

In Angular you rarely write these by hand — the dev server/runtime manages it.

State‑Safety Patterns with HMR

  • Avoid module‑scope side effects. Put initialization behind functions so hot updates don’t re‑run global effects unpredictably.
  • Use signals/store libraries (NgRx, ComponentStore, SignalStore). Stores usually survive hot updates better than ephemeral locals.
  • Reset selectively. For sensitive areas (e.g., auth guards), it’s fine to let the dev server reload fully.

Troubleshooting

  • “It always reloads, never hot updates.”
  • Verify you’re on ng serve with Vite (v17+) or --hmr on older CLI.
  • Check that you’re not editing files outside the HMR graph (e.g., build config, index.html head).
  • “State still resets.”
  • The changed module’s parents may not accept updates — normal for root/main changes.
  • Persist small slices in sessionStorage/localStorage during dev if needed.
  • “CSS not updating?”
  • Ensure styles are in component styles or global styles supported by the dev server. Vite handles CSS HMR very reliably; Webpack does too with style loaders.

Do’s and Don’ts

Do

  • Lean on HMR for UI, style, and component logic tweaks.
  • Keep app bootstrap thin and pure.
  • Organize code to minimize global mutable state.

Don’t

  • Depend on HMR behavior in production code paths.
  • Store secrets in dev memory and assume it survives — HMR can reload at any time.
  • Fight a legitimate full reload — sometimes it’s the right outcome.

Quick Start Cheatsheet (Angular)

Legacy CLI (Webpack)

Shell

ng serve — hmr

Show more lines

Angular 17+ (Vite default)

Shell

ng serve

HMR auto-enabled

``

Verify in console

  • You’ll see logs like “hot update” or “vite:hmr connected”.
  • Changing a component/template should update instantly without a page reload.

Bottom Line

HMR is your dev superpower: edit → instant visual feedback → preserved context. In Angular’s modern Vite world, it’s on by default and lightning‑fast. For legacy Webpack setups, --hmr keeps you equally productive. Use it to iterate rapidly, but keep your app initialization clean so hot updates can apply safely.


메타데이터
post_id
20cf82bdd49f
slug
what-is-hmr-hot-module-replacement-20cf82bdd49f
url
https://medium.com/@acharyaks90/what-is-hmr-hot-module-replacement-20cf82bdd49f
canonical_url
https://medium.com/@acharyaks90/what-is-hmr-hot-module-replacement-20cf82bdd49f
author_url
https://medium.com/@acharyaks90
status
ok
fetched_at
2026-06-11 11:25:07