Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

The CLI in Angular: The Commands That Matter Day to Day

Sean

Platform Writer

Aug 31, 2026
7 min read

The Angular CLI is the ng command, and it does four genuinely different jobs: scaffolding files, running a development server, producing a production build, and - the one people underuse - migrating your code across framework versions.

The CLI in Angular: The Commands That Matter Day to Day

The command reference is long and most of it is rarely touched. The working set is about eight commands, and one of them saves more time than all the others combined.

Table of contents

Getting started and the daily loop

Install the CLI globally, then create and run a workspace.

npm install -g @angular/cli

ng new my-app          # create a workspace, answers a few prompts
cd my-app
ng serve               # dev server with rebuild on change
ng serve --open        # and open a browser
ng serve --port 4300   # when 4200 is taken

ng serve has aliases s and dev. It builds in memory and rebuilds on file changes; it is not what you deploy.

Argument names use dash-case, and a command takes an optional target followed by options - ng build my-app -c production. That pattern is consistent across the whole tool, which makes the reference easier to read than its length suggests.

Generating code, and why it is worth using

ng generate, aliased g, creates files from templates called schematics. It is not just typing-saving: it registers things correctly, follows the project’s configured style, and produces the spec file alongside.

ng g component features/user-profile
ng g service core/auth
ng g guard core/auth
ng g pipe shared/truncate
ng g module features/admin --routing

ng g component foo --dry-run     # show what would happen
ng g component foo --skip-tests  # no spec file

--dry-run is the flag worth remembering. It prints the files that would be created or modified without touching anything, which is how you check a path before generating into the wrong folder and then cleaning up by hand.

Building for production

ng build compiles into an output directory, defaulting to dist/. Production configuration is the default for builds in current versions, applying ahead-of-time compilation, minification, and tree shaking.

ng build                        # production build into dist/
ng build -c staging             # a named configuration
ng build --base-href /app/      # when served from a subpath
ng build --source-map           # source maps for error tracking

Two flags cause most deployment problems. --base-href must match the path the application is served from - get it wrong and every asset request 404s from a subdirectory. And build configurations are defined in angular.json, so a configuration name that works locally must actually exist for CI to use it.

The output is static files. That means any static host with a CDN serves it, and it also means the routing needs a fallback rule - every path that is not a real file must serve index.html, or a deep link refreshed in the browser returns 404 instead of loading the app.

The update command, which is the underused one

ng update is the most valuable command in the tool and the one people avoid out of caution, which is backwards.

ng update                                    # what is available
ng update @angular/core @angular/cli         # update the framework
ng update @angular/core@18 --allow-dirty     # target a version

It does not just bump versions in package.json. It runs migration schematics that rewrite your code for breaking changes - renamed APIs, changed signatures, deprecated patterns. A framework upgrade that would be days of manual work is frequently a command and a review of the diff.

Two rules make it reliable. Commit everything first, so the changes it makes are visible as a clean diff. And update one major version at a time rather than jumping several, because the migrations are written to run in sequence and skipping versions skips the migrations that were meant to run between them.

Teams that avoid this end up several major versions behind, at which point catching up genuinely is the multi-week project they were afraid of. Running it every release cycle keeps it boring.

Testing, linting, and the rest

ng test                 # unit tests, watch mode
ng test --watch=false --browsers=ChromeHeadless   # for CI
ng lint                 # lint the project
g e2e                   # end-to-end, once configured
ng cache clean          # when the build behaves strangely
ng version              # versions of everything, for bug reports

For CI, the important part is disabling watch mode and using a headless browser - the default configuration waits for a browser and for file changes, which in a pipeline means a job that hangs until it times out.

ng cache clean is the first thing to try when builds behave inexplicably. The persistent disk cache is a large speed improvement and occasionally holds something stale.

How this fits the rest of the stack

An Angular build is a folder of static files, which makes hosting it simple and makes the cost mostly about bandwidth and whatever API sits behind it. The RunxBuild hosting calculator prices static hosting alongside the backend service and database so the whole application has one figure. RunxBuild builds static sites straight from a GitHub repository with SPA fallback, custom domains, headers, redirects and rewrites, and includes 120GB of bandwidth at $0.10/GB after.

Useful related references:

FAQ

What is the Angular CLI?

The ng command, which scaffolds projects and files, runs a development server, produces production builds, runs tests and linting, and migrates your code across framework versions. Commands take an optional target followed by dash-case options, consistently throughout.

What does ng update actually do?

More than bump versions. It runs migration schematics that rewrite your code for breaking changes - renamed APIs, changed signatures, deprecated patterns - so a framework upgrade becomes a command and a diff review rather than days of manual editing.

Why does my Angular app 404 when deployed to a subdirectory?

Because --base-href does not match the path it is served from, so every asset request resolves to the wrong URL. Build with ng build --base-href /your-path/ matching exactly where the application lives, including the trailing slash.

Why does a deep link 404 after deploying an Angular app?

Because the build output is static files and the host is looking for a real file at that path. You need a fallback rule serving index.html with a 200 status for anything that is not an existing file, so the router can handle the URL client-side.

How do I run Angular tests in CI?

Disable watch mode and use a headless browser: ng test --watch=false --browsers=ChromeHeadless. The default configuration waits for a browser and for file changes, which in a pipeline produces a job that hangs until it times out.

#Angular CLI#Angular#ng build#Schematics#Deployment