angular/angular-cli · info

NOTICE: Hot Module Replacement (HMR) is enabled for the dev

Error message

NOTICE: Hot Module Replacement (HMR) is enabled for the dev server.
      See https://webpack.js.org/guides/hot-module-replacement for information on working with HMR for Webpack.

What it means

An informational notice logged when the `hmr` option is enabled for the webpack dev-server. HMR swaps modules in the browser without a full reload; because it can produce surprising state behavior, Angular prints a notice pointing to webpack's HMR guide. It is purely informational, not a failure.

Source

Thrown at packages/angular_devkit/build_angular/src/builders/dev-server/webpack-server.ts:85

  options: NormalizedDevServerOptions,
  builderName: string,
  context: BuilderContext,
  transforms: {
    webpackConfiguration?: ExecutionTransformer<webpack.Configuration>;
    logging?: WebpackLoggingCallback;
    indexHtml?: IndexHtmlTransform;
  } = {},
): Observable<DevServerBuilderOutput> {
  // Check Angular version.
  const { logger, workspaceRoot } = context;
  assertCompatibleAngularVersion(workspaceRoot);

  async function setup(): Promise<{
    browserOptions: BrowserBuilderSchema;
    webpackConfig: webpack.Configuration;
  }> {
    if (options.hmr) {
      logger.warn(tags.stripIndents`NOTICE: Hot Module Replacement (HMR) is enabled for the dev server.
      See https://webpack.js.org/guides/hot-module-replacement for information on working with HMR for Webpack.`);
    }

    // Get the browser configuration from the target name.
    const rawBrowserOptions = await context.getTargetOptions(options.buildTarget);

    if (rawBrowserOptions.outputHashing && rawBrowserOptions.outputHashing !== OutputHashing.None) {
      // Disable output hashing for dev build as this can cause memory leaks
      // See: https://github.com/webpack/webpack-dev-server/issues/377#issuecomment-241258405
      rawBrowserOptions.outputHashing = OutputHashing.None;
      logger.warn(`Warning: 'outputHashing' option is disabled when using the dev-server.`);
    }

    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
    const browserOptions = (await context.validateOptions(
      {
        ...rawBrowserOptions,
        watch: options.watch,

View on GitHub (pinned to bb72145f9a)

Solutions

  1. If HMR is wanted, keep the flag and use the linked webpack HMR guide to handle module acceptance correctly
  2. Remove `--hmr` or set `"hmr": false` to return to standard live-reload behavior
  3. If the notice is unexpected, check angular.json serve options and CI scripts for a leftover hmr flag
  4. Combine with `"liveReload": false` only if you understand components will not fully reload on failure

Example fix

// before (angular.json serve options)
"options": { "hmr": true }
// after
"options": { "hmr": false }
Defensive patterns

Strategy: validation

Validate before calling

// angular.json serve options check
if (serveOptions.hmr === true) {
  console.log('HMR enabled: expect module-swap notices; see webpack HMR guide.');
}

Type guard

function isHmrEnabled(o: { hmr?: boolean }): boolean {
  return o?.hmr === true;
}

Prevention

When it happens

Trigger: Running `ng serve --hmr` or setting `"hmr": true` in the dev-server target options; logged at the start of `setup()` before the browser configuration is resolved.

Common situations: Developers enabling HMR for faster UI iteration; often combined with `--live-reload=false`; sometimes left in angular.json after an experiment and later noticed in logs.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/ddb8d1ea74185697. Report an issue: GitHub.