Blog

Deploying Apps with the Angular CLI

Key Takeaways

  • ng build writes build artifacts to disk; ng serve provides a development server with rebuilds and live updates.
  • Use ng build --configuration production for an explicit production build. An unqualified build follows the target's configured default.
  • Inspect angular.json and the generated files before choosing your host's publish directory.
  • For subdirectory hosting, match --base-href to the public URL path and configure client-side route fallback.
  • Server-rendered applications need a serving runtime; fully prerendered applications can use static hosting.

To deploy a client-side Angular application, create a production build, publish its browser output to a web server or static host, and configure routing for direct page requests. The Angular CLI prepares the files; your hosting configuration determines whether those files work at the intended URL. ng serve is the development workflow, not the deployment artifact.

What Does ng build Do?

ng build invokes the selected project's build target from angular.json. A target is a configured task; its builder is the tool that executes it. For an application, that typically means compiling TypeScript and Angular templates, bundling resources, and writing the resulting files to disk. If workspaces and projects are unfamiliar, see Angular workspaces, applications, and libraries.

New applications use the esbuild-based @angular/build:application builder. Older or customized workspaces may use webpack or another builder, so check your configuration rather than assuming the bundler. Angular's existing webpack-based browser builder is now deprecated; the build-system migration guide covers the supported migration path.

ng build vs ng serve

CommandPurposeResult
ng buildCreate a build artifactFiles written to the configured output directory
ng serveDevelop locallyA running development server that rebuilds on changes

The useful distinction is the deliverable, not whether every implementation stores every intermediate file in memory. With ng serve, you work against a development server with live updates. With ng build, you produce files you can inspect and publish.

Angular CLI Build for Production

Run these commands from your workspace root, using the CLI installed for your project. Replace my-app with the application name under projects in angular.json:

ng build my-app --configuration production
ng build my-app --configuration development

-c production is shorthand for --configuration production. Without an explicit configuration, the target's defaultConfiguration determines the selection. Generated applications set the build default to production; if no default configuration is set, the target uses its base options and builder defaults. Omitting a flag does not inherently mean a development build.

Production optimization includes minification, tree shaking, and dead-code elimination: making code smaller and excluding code the build tools can establish is unused. Ahead-of-time (AOT) compilation converts Angular templates during the build, but it isn't exclusive to production: new CLI applications enable AOT by default. See Angular AOT vs JIT compilation for the distinction.

Build Targets, Configurations, and Environments

A target answers “what task should run?” A configuration answers “which settings should that task use?” The historical --target and --environment build options are obsolete; named configurations selected through --configuration replaced that older model. The modern term target still exists, but it means a configured task such as build or serve.

For a workspace already using @angular/build:application, this JSON fragment shows settings for projects.my-app.architect.build. It is not a complete workspace file: merge these settings into the existing target, retaining its entry point, TypeScript configuration, assets, styles, and other required options.

{
  "builder": "@angular/build:application",
  "options": {
    "outputPath": {
      "base": "dist/my-app",
      "browser": "browser"
    }
  },
  "configurations": {
    "production": {
      "optimization": true,
      "outputHashing": "all",
      "sourceMap": false
    },
    "development": {
      "optimization": false,
      "sourceMap": true
    },
    "qa": {
      "baseHref": "/qa/"
    }
  },
  "defaultConfiguration": "production"
}

Configuration names must exist in the target. To combine the production settings with the QA base path, use one comma-separated argument:

ng build my-app --configuration production,qa

Configurations apply from left to right; later values win when settings conflict. Explicit command-line options override configuration values. Do not repeat --configuration to express composition.

Environment Files Are Build Inputs, Not Secrets

A configuration name doesn't automatically select an environment file. Configure fileReplacements when you need different source files for different environments; ng generate environments can create that setup. Environment files included in the browser bundle are visible to users, so never place private credentials in them.

Where Does ng build Put Its Output?

The selected builder, outputPath, and configuration determine the output location. With the application-builder fragment above, browser files go into dist/my-app/browser. Other workspaces can use different layouts; dist is not a universal publish directory.

You can inspect the target with ng config:

ng config projects.my-app.architect.build

Check the base options and the selected configurations, then inspect the location reported by the completed build. For this client-side example, publish the contents of dist/my-app/browser, including its generated index.html and resources—not an assumed parent directory.

Set Angular base href for Subdirectory Hosting

The HTML <base href> establishes the document base URL for relative references. Angular's normal path-based routing also uses the application's base path. For an application hosted under /myapp/, build with:

ng build my-app --configuration production --base-href /myapp/

The generated index.html contains:

<base href="/myapp/">

Your host must actually serve the browser files at /myapp/. The flag does not create that server mapping or upload anything. Keep the trailing slash: this is a directory-style base URL. An incorrect base can send script, stylesheet, and navigation requests to the wrong paths.

base-href and deploy-url Are Not Interchangeable

--base-href sets the application's document base. --deploy-url customizes resource URL prefixes in generated HTML and component stylesheets, for scenarios such as a separate asset CDN. It does not replace the router's application base path. Prefer base-href for ordinary subdirectory hosting; use asset-specific configuration only when your hosting layout requires it.

Publish the Files and Configure Route Fallback

For the example above, copy the browser output to the directory your host exposes at /myapp/, or select that output as the hosting platform's publish directory.

angular.json + selected configuration
                 |
                 v
              ng build
                 |
                 v
       dist/my-app/browser/
                 |
                 v
       Static host at /myapp/
       - serve existing files
       - app route fallback: /myapp/index.html

A single-page application (SPA) handles navigation in the browser after it loads. However, opening or refreshing /myapp/users/42 makes a direct request to the host. Configure the host to return /myapp/index.html for client-side routes so Angular can load and interpret the URL. Without that fallback, a route that works through in-app navigation can return a server 404 on refresh.

Scope the fallback to application routes. Keep API endpoints and static-file handling separate rather than returning application HTML for every failed request.

SSR and Prerendering Need a Different Deployment Plan

The application builder can also build server-side rendering (SSR) output and prerender pages during ng build; separate build commands are not universally required. Request-time SSR needs deployment of the server artifact and a compatible runtime, not just the browser folder.

A fully prerendered build can use static hosting. In an SSR-enabled application, outputMode: "static" generates prerendered route HTML without a server artifact; preserve those generated pages when publishing. Consult Angular's rendering guide before applying SPA-only fallback rules, and review client-side vs server-side rendering if you're choosing between the two.

Production Checklist

  • Build deliberately: select the intended project and configuration, and stop deployment if the build fails.
  • Inspect the artifact: confirm the publish directory and the generated base tag.
  • Test the real public path: load /myapp/, navigate to a nested route, then refresh it and open it directly.
  • Check network requests: verify scripts, styles, images, and lazy-loaded routes load successfully without receiving fallback HTML.
  • Verify backend access: test API requests from the deployed origin, not only through your development setup.

The deployment is complete when the published artifact works at its real URL—not merely when the CLI reports a successful build.

FAQ

What replaced ng build --prod?

Use ng build --configuration production, or ng build -c production. The --prod flag was deprecated in Angular CLI 12 and removed in Angular CLI 14.

How do I build an Angular app for production?

Run ng build my-app --configuration production from the workspace root, replacing my-app with your project name. Confirm that the production configuration contains your intended settings before publishing the browser output.

Where does ng build put its output?

The location depends on the build target's outputPath, selected configuration, and builder. Application-builder browser output commonly lives under dist/my-app/browser; inspect your workspace and completed build rather than assuming the path.

How do I deploy an Angular app under a subdirectory?

For hosting under /myapp/, build with --base-href /myapp/ and serve the browser output at that path. For path-based client-side routing, configure application routes to fall back to /myapp/index.html and test direct navigation and refreshes.

What is the difference between ng build and ng serve?

ng build writes build artifacts to disk for inspection and deployment. ng serve runs a development server that rebuilds the application as files change; it is not your production publish directory.

Further Reading

Written by Sam Erickson

Software engineer. I write every article on StackChief myself. Author of Mastering the Tech Interview. More about me