skip to content

Build Tools & Bundlers

The rival bundlers, transpilers and framework CLIs that turn source into shipped files, each with its own config, CLI and plugins. Interviewers ask which one fits a project and what leaving it costs.

on this pageshow

explore

→ has its own guide

questions

page 1 of 2

With the Angular CLI, how does `ng serve` differ from `ng build`, and why is the dev server's output never what you deploy?

level: juniorimportance: must knowfreq 70%

answer

  1. two builders, one build pipeline
  2. @angular/build:dev-server wraps application
  3. development vs production configuration
  4. in memory, watched, served by Vite
  5. dist/<project>/browser is the artifact

basics

~20 s

ng serve runs the @angular/build:dev-server builder, which builds the app with its development configuration in memory, watches files and reloads the browser. ng build runs @angular/build:application with the production configuration and writes optimized, hashed files to dist/<project>/browser for deployment.

solid answer

~40 s

Both commands build the application with the same `@angular/build:application` pipeline, but for different purposes. `ng build` (alias `ng b`) runs the `build` target, whose `defaultConfiguration` is `production` in a new project: optimization on, no source maps, `outputHashing: 'all'`, licenses extracted. It writes to `dist/<project>/browser` (plus `server` when SSR is on), and that folder is the deployable artifact. `ng serve` (aliases `ng s`, `ng dev`) runs the `serve` target's `@angular/build:dev-server` builder. It points at `build:development` by default, which turns optimization off and source maps on. It keeps the output in memory, hands it to a Vite-based server, rebuilds only what changed on each save, and reloads or hot-replaces in the browser. It is unminified, unhashed and not written to `dist`, so it is a development tool, never a deployment.

code

json · 16 lines
json
"build": {
  "builder": "@angular/build:application",
  "defaultConfiguration": "production",
  "configurations": {
    "production": { "outputHashing": "all" },
    "development": { "optimization": false, "extractLicenses": false, "sourceMap": true }
  }
},
"serve": {
  "builder": "@angular/build:dev-server",
  "defaultConfiguration": "development",
  "configurations": {
    "production": { "buildTarget": "app:build:production" },
    "development": { "buildTarget": "app:build:development" }
  }
}

go deeper

for a junior

Know that ng serve is for local development with reload on save, and ng build creates the production files in dist to deploy.

for a middle

Explain the build and serve targets, the dev-server's buildTarget, and exactly which options the production and development configurations change.

for a senior

Use ng serve --configuration production to reproduce production-only bugs, knowing what changes (HMR off, optimized code), and keep CI deploying only ng build artifacts.

for a principal

Standardise how every app in the organisation builds and serves, so local, CI and production share one configuration model and differences are deliberate.

## Two targets, two builders In `angular.json` every command maps to a **target** that names a **builder**, the function that does the work. A project created by Angular CLI 22 has: | Target | Builder | `defaultConfiguration` | Used by | |---|---|---|---| | `build` | `@angular/build:application` | `production` | `ng build` / `ng b` | | `serve` | `@angular/build:dev-server` | `development` | `ng serve` / `ng s` / `ng dev` | The dev-server builder does not have its own compiler. Its `buildTarget` option points at the build target with a configuration: `app:build:development` by default, `app:build:production` when you run `ng serve --configuration production`. It then runs that same application build internally. ## What the two configurations change The generated `build` target keeps most values at the builder's schema defaults and overrides a few per configuration: - **production**: `outputHashing: 'all'` and the budgets. Everything else uses the schema defaults, so `optimization` is `true`, `sourceMap` is `false`, `extractLicenses` is `true` and `namedChunks` is `false`. - **development**: `optimization: false`, `extractLicenses: false`, `sourceMap: true`, with `outputHashing` left at its default of `none`. So `ng build` gives minified, tree-shaken, cache-busted files with a separate license file. `ng serve` gives readable code with source maps, which is fast to rebuild and easy to debug. ## What `ng serve` does on top 1. **Builds in memory.** The Angular docs describe the dev server as generating a development build in memory and passing the results to Vite to serve. Vite is used here *only* as a development server and cannot be configured directly. Nothing is written to `dist/`. 2. **Watches and rebuilds incrementally.** `watch` defaults to `true`. On save, only affected files are recompiled. 3. **Updates the browser.** `liveReload` defaults to `true`. Style and template edits are hot-replaced (HMR) where possible; other changes trigger a full page reload. 4. **Prebundles dependencies.** Third-party packages are processed once on first start, so later rebuilds skip them. The `prebundle` option controls it. 5. **Serves on a local address.** By default it serves on `localhost` port `4200`. Host, port, HTTPS and proxying to a backend are dev-server options too. ## Why you never deploy the dev server - The output is **unoptimized**: no minification, no tree-shaking beyond what the bundler does by default, and large source maps. - File names are **not content-hashed** for entry bundles, so browsers and CDNs cannot cache them safely. - It exists only **in the memory of a process** built for fast rebuilds and debugging. It has development-only behaviour such as live reload and prebundling, and it is not designed or hardened to serve real traffic. - `ng build` produces a **static folder** that any web server or CDN can host (or a server bundle for SSR). That is what CI should build and ship. ## Commands you actually type ```bash ng serve # development build, in memory, http://localhost:4200 ng serve --configuration production # check production settings locally ng build # production build into dist/<project>/browser ng build --configuration development # unminified build written to disk ``` `ng serve --configuration production` is handy for reproducing a production-only bug. Note that it serves the production build settings through the dev server, and that HMR turns itself off because of `outputHashing: 'all'`. ## Side by side | Aspect | `ng serve` | `ng build` | |---|---|---| | Builder | `@angular/build:dev-server` | `@angular/build:application` | | Default configuration | `development` | `production` | | Output | In memory | `dist/<project>/browser` (and `server` for SSR) | | Minified | No | Yes | | Source maps | Yes | No | | Hashed entry file names | No | Yes (`outputHashing: 'all'`) | | Watches and reloads | Yes | No, unless `--watch` | | Purpose | Local development | The deployable artifact | The table is a summary of the *generated* defaults. Every row can be changed per configuration, which is why teams sometimes add a `staging` configuration that serves or builds with production-like settings. ## Common interview traps - Saying `ng serve` "uses Webpack". New projects have used the esbuild-based application builder since v17, taken directly from the `@angular/build` package since v20, and the webpack builders in `@angular-devkit/build-angular` are deprecated in v22. - Thinking `ng build` defaults to a development build. In generated projects `defaultConfiguration` is `production`. - Looking for the output in `dist/<project>` directly. The application builder writes browser files to a `browser` subfolder.

  • Where does `ng build` put its output, and why did that surprise teams moving from the old builder?
    By default the application builder writes to `dist/<project>/browser`, plus `dist/<project>/server` when SSR is enabled. The old `browser` builder wrote straight into `dist/<project>`, so deploy scripts that copied that folder broke. Adjust the scripts, or configure `outputPath` so the browser folder name is empty.
  • Why might `ng serve` show a brief flash of unstyled content that `ng build` output never shows?
    The dev server defers processing stylesheets until they are first used, to keep rebuilds fast. The Angular docs note this can cause a small flash of unstyled content on startup. It does not happen in builds outside the dev server.

saying these in an interview costs you the question

  • Deploys the output of ng serve or copies files out of the dev server
  • Believes ng build produces a development build unless --prod is passed
  • Says ng serve in a new project runs a webpack dev server
  • Expects the built browser files directly in dist/<project> with the application builder
  • Thinks ng serve has its own compiler separate from the application builder
open as a page

With the Angular CLI, what does `ng generate library` add to a workspace, and what must happen before an app in that workspace can import it?

level: juniorimportance: must knowfreq 55%

basics

~20 s

ng generate library adds a library project under projects/ with its own ng-packagr build target, ng-package.json, package.json and public-api.ts, and maps the library name to dist/<name> in tsconfig paths. Apps import the built output, so build the library first.

open as a page

With the Angular CLI, what does `ng generate component` create in a v22 project, and how do you preview it before any file is written?

level: juniorimportance: must knowfreq 72%

basics

~10 s

ng generate component user-card runs the @schematics/angular:component schematic, which creates a user-card/ folder with user-card.ts, .html, .css and .spec.ts for a standalone UserCard class; --dry-run (-d) lists those files without writing them.

open as a page

With the Angular CLI's `ng serve`, how do you forward `/api` requests to a backend running locally on another port, and why does that not help in production?

level: juniorimportance: must knowfreq 62%

basics

~20 s

Create a proxy file such as src/proxy.conf.json mapping /api/** to the backend's target URL, set proxyConfig on the serve target, and restart ng serve. Only the dev server reads it, so production needs its own reverse proxy or CORS.

open as a page

With the Angular CLI, what does `ng update @angular/core @angular/cli` do beyond changing version numbers in package.json?

level: juniorimportance: must knowfreq 66%

basics

~20 s

ng update resolves compatible target versions for the named packages and their package groups, checks peer dependencies, requires a clean git tree, rewrites package.json, installs, then runs each updated package's migration schematics to change your code and configuration.

open as a page

With the Angular CLI, why does ng build produce an optimized, hashed bundle while ng serve does not, in a newly generated angular.json?

level: juniorimportance: must knowfreq 62%

basics

~10 s

In a new Angular CLI project, the build target's defaultConfiguration is production, which adds budgets and outputHashing: 'all', while serve defaults to development, whose buildTarget turns optimization off and source maps on.

open as a page

How do you start a new Vue 3 project with create-vue, and why must the command be npm create vue@latest rather than npm create vue?

level: juniorimportance: must knowfreq 35%

basics

~10 s

Run npm create vue@latest, answer the prompts, then install dependencies and start the dev server. The @latest tag matters because without it npm may reuse a cached, outdated create-vue.

open as a page

In Angular's application builder, what do `optimization`, `sourceMap`, `outputHashing` and `namedChunks` control, and how do production and development builds set them?

level: middleimportance: must knowfreq 55%

basics

~20 s

optimization minifies, tree-shakes and inlines critical CSS and fonts; sourceMap emits maps; outputHashing hashes file names; namedChunks names lazy chunks. Production keeps optimization on, maps off and hashing all; development turns optimization off and maps on.

open as a page

In an Angular CLI library project, why does the production build set `compilationMode` to `partial`, and what goes wrong if you publish a development build?

level: middleimportance: must knowfreq 45%

basics

~20 s

Partial compilation emits Angular code not tied to one Angular runtime version, and the consuming app's build finishes it. A development build uses full compilation, which only works with the exact Angular version it was built against.

open as a page

With the Angular CLI, what does `ng add <package>` do that a plain `npm install <package>` does not?

level: middleimportance: must knowfreq 55%

basics

~20 s

ng add picks a version compatible with the workspace's installed packages, installs it, then runs the package's own ng-add schematic to wire it in: providers, config, styles, angular.json targets. npm install only downloads the package.

open as a page

Why does the Angular CLI refuse to update `@angular/core` from v20 straight to v22, and how do you move an app across several majors?

level: middleimportance: must knowfreq 62%

basics

~10 s

Migrations and deprecation windows assume one major at a time, so ng update refuses bigger jumps for @angular/* packages. Run ng update @angular/core@^21 @angular/cli@^21, build, test and commit, then repeat for ^22.

open as a page

In an Angular CLI project, how do you add a staging build configuration with its own environment file, and what does fileReplacements do?

level: middleimportance: must knowfreq 65%

basics

~10 s

Add a staging entry under the Angular CLI build target's configurations whose fileReplacements swaps src/environments/environment.ts for environment.staging.ts at compile time, give serve a matching buildTarget, and build with ng build -c staging.

open as a page

What do the Angular CLI's `ng serve` options `host`, `port` and `ssl` control, and what do you change to open the dev server from another device?

level: juniorimportance: should knowfreq 40%

basics

~20 s

host sets the interface the dev server listens on (default localhost), port its port (default 4200), and ssl switches to HTTPS. To reach it from a phone, listen on 0.0.0.0 and open the machine's address; add allowedHosts for custom hostnames.

open as a page

With the Angular CLI dev server, which edits are hot-replaced without a page reload, which cause a full reload, and what can switch HMR off?

level: middleimportance: should knowfreq 40%

basics

~10 s

ng serve hot-replaces global styles and component templates and styles; TypeScript changes reload the page. HMR is off with --no-hmr, without live reload, in JIT builds, or when outputHashing is all or bundles.

open as a page

How do you give an error-reporting service readable stack traces for an Angular CLI production build without letting browsers download your source maps?

level: middleimportance: should knowfreq 35%

basics

~10 s

Set the production sourceMap to { "scripts": true, "hidden": true }. The builder writes .map files without the sourceMappingURL comment. CI uploads them to the error-reporting service and deletes them before deploying.

open as a page

In an Angular CLI library, what is `public-api.ts` for, and how does `ng-package.json` connect it to what consuming apps can import?

level: middleimportance: should knowfreq 42%

basics

~10 s

public-api.ts is the library's entry file: ng-package.json names it in lib.entryFile, and ng-packagr packages what it exports into the published entry point. Anything not exported there cannot be imported by consumers by package name.

open as a page

In an Angular CLI workspace, how do you make every `ng generate component` default to SCSS and no spec file, and which setting wins?

level: middleimportance: should knowfreq 42%

basics

~10 s

Add "@schematics/angular:component": { "style": "scss", "skipTests": true } under a schematics block in angular.json. Project-level entries override workspace-level ones, which override global ones, and a flag typed on the command line overrides them all.

open as a page

In Angular schematics, what is the virtual `Tree`, and why does a schematic that throws halfway leave every file on disk unchanged?

level: middleimportance: should knowfreq 35%

basics

~20 s

A schematic's Tree is an in-memory view of the workspace: the files on disk as a base plus a staging area of recorded changes. Nothing reaches disk until the whole schematic succeeds, so an error discards everything.

open as a page

In an Angular CLI 22 application build, what does `outputMode: 'static'` versus `'server'` change in what `ng build` produces and how you deploy it?

level: middleimportance: should knowfreq 45%

basics

~20 s

outputMode 'server' emits a browser folder plus a server folder with server.mjs that you run under Node; it needs the server and ssr.entry options. outputMode 'static' emits only browser files, prerendered where possible, for any static host.

open as a page

With the Angular CLI, when do you run `ng update <package> --migrate-only --from <version>`, and how does it differ from a normal `ng update`?

level: middleimportance: should knowfreq 32%

basics

~20 s

Use it when versions were bumped outside ng update (a package manager, a bot, a shared catalog), so migrations never ran. It installs nothing and runs migrations above --from up to --to, which defaults to the installed version.

open as a page

In angular.json, which budget types can the Angular CLI enforce, and how do maximumWarning, maximumError and baseline decide whether a build fails?

level: middleimportance: should knowfreq 45%

basics

~10 s

Angular CLI budgets in angular.json have a type (initial, bundle, all, allScript, any, anyScript, anyComponentStyle) and thresholds. Crossing maximumWarning logs a warning; crossing maximumError fails the build. Percentages are relative to a baseline.

open as a page

In a multi-project Angular CLI workspace, how does ng build decide which project to build, and how do you target one explicitly?

level: middleimportance: should knowfreq 40%

basics

~20 s

An Angular CLI command such as ng build picks the only project with that target, or the project containing the current directory; otherwise it errors. Name the project explicitly, as in ng build admin or ng run admin:build:production.

open as a page

In create-vue 3.24, what does selecting ESLint generate, why is Oxlint always added with it, and how does the Prettier choice fit in?

level: middleimportance: should knowfreq 20%

basics

~20 s

ESLint adds a flat eslint.config with the Vue and TypeScript presets, plus Oxlint with an .oxlintrc.json; the lint script runs both. Oxlint is always included and eslint-plugin-oxlint turns off ESLint rules it covers. Prettier adds its own config and a format script.

open as a page

When scaffolding an internal tool with create-vue, what do the TypeScript, Router, Pinia and Vitest choices each add to the generated project?

level: middleimportance: should knowfreq 26%

basics

~20 s

TypeScript adds tsconfig files, env.d.ts and a type-checking build script; Router adds vue-router with src/router and two views; Pinia adds pinia and a counter store; Vitest adds vitest.config, a jsdom test setup and an example spec.

open as a page

An Angular app still builds with `@angular-devkit/build-angular:browser`; how do you migrate it to the application builder, and what breaks along the way?

level: seniorimportance: should knowfreq 45%

basics

~10 s

Run ng update @angular/cli --name use-application-builder: it switches to the application builder, renames main to browser and drops webpack-only options. Then fix the new dist/<project>/browser output path, non-ESM imports and any custom webpack setup.

open as a page

When a new release of your internal Angular UI-kit library makes one app fail to build and another throw injection errors, what do you check and fix?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Check that the release is a production, partial build published from dist, that it was not built with a newer Angular than the app, that @angular packages stay peerDependencies so apps get one copy, and whether an export was removed.

open as a page

How would you build an Angular CLI schematic so that `ng generate` scaffolds your team's feature folder with a routes file, a page component and a data service?

level: seniorimportance: should knowfreq 28%

basics

~20 s

Write a schematics collection with a feature schematic whose rule renders url('./files') templates with applyTemplates, moves them into place and mergeWiths them into the tree; build it, list it in cli.schematicCollections, test it with SchematicTestRunner.

open as a page

An Angular CLI app deployed under `/shop/` loads a blank page and its deep links 404; how do `baseHref`, `deployUrl` and the server config each factor in?

level: seniorimportance: should knowfreq 42%

basics

~10 s

Build with baseHref /shop/ so index.html gets <base href="/shop/"> and scripts and routes resolve under it, and configure the server to return /shop/index.html for unknown paths. deployUrl only prefixes asset URLs, for CDN-style setups.

open as a page

When `ng update @angular/core@22` stops with 'Incompatible peer dependencies found' because a third-party library only accepts Angular 21, how do you resolve it and when is `--force` acceptable?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Name a library release that accepts Angular 22 in the same ng update; without one, wait, replace or patch the library. --force only skips the CLI's check, so use it only after proving the library works on 22.

open as a page

An Angular CLI app built with ng build -c staging ships unhashed file names and skips budgets; why, and how should angular.json be fixed?

level: seniorimportance: should knowfreq 38%

basics

~20 s

An Angular CLI configuration named with -c replaces defaultConfiguration instead of stacking on it, so staging gets only the base options and its own overrides. Repeat production's settings in staging, or build with -c production,staging.

open as a page

showing 1–30 of 37