skip to content

In Angular, what does isDevMode() return, and what actually differs between development mode and production mode at runtime?

level: middleimportance: should knowfreq 30%

answer

  1. one global flag underneath
  2. decided by the build
  3. extra checks and debug hooks
  4. not a feature flag

basics

~20 s

Angular's isDevMode() returns true unless the app was built with script optimization or enableProdMode() was called. Development mode keeps dev-only assertions, descriptive error messages, the window.ng debug global and DevTools support; production strips them for size and speed.

solid answer

~40 s

`isDevMode()` from `@angular/core` reads the global `ngDevMode` flag: it returns `true` unless the flag has been set to `false`. The Angular CLI sets it to `false` when a build optimizes scripts, which the default production configuration does, and `ng serve` uses a development configuration, so it is `true` there. `enableProdMode()` also sets it but is discouraged, since the CLI handles it. Development mode keeps framework code guarded by `ngDevMode`: extra assertions and consistency checks, full error messages with links, the `window.ng` debug utilities and the hooks Angular DevTools uses. In production those branches are compiled out. Use `isDevMode()` for dev-only diagnostics such as verbose logging; do not use it for feature flags or security decisions, and do not confuse it with your own `environment.production` file, which Angular never reads.

go deeper

for a junior

Know that isDevMode() is true when serving locally and false in an optimized production build, and that production drops debug features.

for a middle

Explain the ngDevMode flag, how the CLI switches it off at build time, and what development mode adds: checks, messages, window.ng and DevTools.

for a senior

Keep isDevMode() to diagnostics, never configuration or security, and set up a non-optimized build when full messages and tooling are needed to diagnose an issue.

for a principal

Separate build mode from environment configuration across projects so that a debug build of production code is possible without changing behaviour.

## One flag underneath Angular's framework code is sprinkled with checks like `if (ngDevMode) { ... }` and `ngDevMode && 'message'`. `ngDevMode` is a global. `isDevMode()` is the public way to read it: ```ts export function isDevMode(): boolean { return typeof ngDevMode === 'undefined' || !!ngDevMode; } ``` So development mode is the **default**: it holds unless something sets `ngDevMode` to `false`. ## Who decides the mode | How the app is built or started | `ngDevMode` | `isDevMode()` | | :-- | :-- | :-- | | `ng serve` (development configuration) | left defined for debugging | `true` | | `ng build` with the default production configuration (scripts optimized) | defined as `false` at build time | `false` | | Any build with `"optimization": false` | not forced off | `true` | | Code that calls `enableProdMode()` before bootstrap | set to `false` at runtime | `false` | The CLI's application builder injects `ngDevMode: false` as a compile-time constant whenever script optimization is on, which lets the minifier delete every dev-only branch. `enableProdMode()` still exists, but its own documentation discourages it because the CLI already handles the switch. ## What development mode adds - **Assertions and consistency checks** inside the framework that catch misuse early, including extra verification passes in change detection (covered in depth by the change-detection topic). - **Descriptive error messages**: a missing provider reports the token and its dependency path instead of a bare `NG0201`, plus a link to the error reference page. - **The `window.ng` debug utilities**: `ng.getComponent`, `ng.applyChanges`, `ng.getInjector` and friends. - **Angular DevTools support**: the extension refuses optimized builds because the hooks it needs are compiled out. - **Dev-only warnings**, such as console hints about misconfigurations. ## What production mode gains 1. **Smaller bundles**: messages, assertions and debug utilities are removed by tree-shaking. 2. **Less work per change detection pass**: no extra verification. 3. **No debugging surface** in the page: nothing publishes internals on `window`. ## Using `isDevMode()` in application code Reasonable uses: - verbose logging or extra `console` diagnostics during development; - registering development-only providers, such as a mock interceptor, behind a check at bootstrap; - showing a small "development build" banner. Things it is **not** for: - **Feature flags or environment configuration**: a staging build with optimization on reports `false` just like production. Use your own configuration for API URLs and toggles. - **Security**: anything gated only by `isDevMode()` is still in the shipped source unless the bundler removes it, and a non-optimized build flips it on. - **Replacing `environment.ts`**: the `environment.production` field in a project's environment files is just your data; Angular itself never reads it. It is common for teams to confuse the two. ## A common trap: behaviour that differs between modes Because development mode runs extra checks, some problems only show up there, and the absence of those checks can hide problems in production. Two practical consequences: - A bug report from production with a bare error code is best reproduced in a **non-optimized** build, where the same failure produces a full message. - Code must never *depend* on a dev-only side effect: anything that works only because a debug utility or dev-only branch exists will break when optimization removes it. ## Interview framing A crisp answer: `isDevMode()` reflects the `ngDevMode` flag; optimized CLI builds turn it off at compile time; development mode buys checks, readable errors and debugging tools at the cost of size and speed; and it is a diagnostics switch, not a configuration system.

  • Does setting production: true in an Angular project's environment.ts turn on production mode?
    No. `environment.ts` is ordinary application data that your code reads; Angular never looks at it. Production mode comes from `ngDevMode`, which the CLI turns off when a build optimizes scripts, or from calling `enableProdMode()`. A build with `optimization: false` stays in development mode whatever the environment file says.
  • Why is isDevMode() a poor choice for toggling a feature in an Angular app?
    It reflects how the bundle was optimized, not which environment it runs in: staging and production builds usually both report `false`, and a debug build of production code reports `true`. Feature toggles belong in explicit configuration or a flag service that you control per environment.

saying these in an interview costs you the question

  • isDevMode() reads environment.production from environment.ts.
  • Every Angular app must call enableProdMode() in main.ts before deploying.
  • Development mode and production mode run exactly the same framework code.
  • isDevMode() is a safe way to hide admin features from end users.
  • ng serve runs in production mode unless you pass a special flag.