1. Installing the CLI & Creating Your First App
You don't need to permanently install the Angular CLI globally — npx always
runs the right version for the command you're calling. Installing it globally is still
convenient if you're generating projects often, so both are worth knowing.
# Run without installing anything globally
npx @angular/cli@latest new my-app
# Or install once, then use `ng` directly
npm install -g @angular/cli@latest
ng new my-app
ng new asks a handful of questions — stylesheet format, SSR, routing — and
scaffolds a complete, runnable project. The flags below skip the prompts, which is
worth doing once you know what you want:
ng new my-app --style=scss --ssr=false --routing=true
cd my-app
ng serve
ng serve starts a local dev server (default: http://localhost:4200)
with live reload — save a file, the browser updates without a manual refresh.
2. The Build System: Vite & esbuild
Modern Angular projects use the @angular/build:application builder, which
runs on esbuild for production bundling and Vite for the
dev server. The practical effect: cold starts and rebuilds that used to take seconds now
take a fraction of a second.
{
"projects": {
"my-app": {
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"outputPath": "dist/my-app",
"index": "src/index.html",
"browser": "src/main.ts",
"tsConfig": "tsconfig.app.json"
}
},
"serve": {
"builder": "@angular/build:dev-server"
}
}
}
}
}
You'll rarely hand-edit this — ng generate and ng add schematics
update it for you — but knowing it exists demystifies what ng build and
ng serve actually invoke.
Week 20 (Performance) and Week 21 (SSR) both involve reading build output and bundle stats. Recognizing this config now means you won't be learning it cold under a deadline.
3. Project Anatomy — What Every File Does
A freshly generated app looks like this:
my-app/
├── public/ # Static assets copied as-is (favicon, images)
├── src/
│ ├── app/
│ │ ├── app.ts # Root standalone component
│ │ ├── app.html
│ │ ├── app.css
│ │ ├── app.config.ts # Application-wide providers (see Section 4)
│ │ └── app.routes.ts # Route definitions
│ ├── index.html # The single HTML shell the app mounts into
│ ├── main.ts # Entry point — calls bootstrapApplication()
│ └── styles.css # Global styles
├── angular.json # Build/serve/test configuration
├── package.json
├── tsconfig.json # Base TypeScript config
├── tsconfig.app.json # Extends base, used for the app build
└── tsconfig.spec.json # Extends base, used for tests
The only two files you'll touch on day one are app.ts and app.html.
Everything else is configuration you'll grow into over the next few weeks — you'll meet
app.config.ts properly in Week 3, and app.routes.ts in Week 10.
4. Workspaces, Multi-App & Shared Libraries
A single Angular workspace can contain more than one application, plus shared libraries they both depend on — useful for an admin app and a public app that share a UI kit, for example.
# Create an empty workspace (no default app)
ng new my-workspace --no-create-application
cd my-workspace
# Add two applications
ng generate application admin
ng generate application storefront
# Add a shared library
ng generate library ui-kit
Each application gets its own entry in angular.json under
projects, and the library gets a TypeScript path mapping so both apps can
import it directly:
{
"compilerOptions": {
"paths": {
"ui-kit": ["projects/ui-kit/src/public-api.ts"]
}
}
}
5. Environment Configuration & Build Targets
angular.json supports named configurations (typically
development and production) that swap build options — and
optionally whole files — based on how you build.
# Uses the "production" configuration by default
ng build
# Explicit configuration
ng build --configuration=development
ng serve --configuration=production
The classic pattern for environment-specific values is a pair of files swapped at build
time via fileReplacements:
export const environment = {
production: false,
apiUrl: 'http://localhost:3000/api',
};
angular.json then replaces that file with
environment.production.ts when you build with the
production configuration — same import path in your code, different values
at build time, with zero runtime cost.
6. Editor Setup & DevTools
Two tools are worth installing before Week 3:
- Angular Language Service — the official VS Code extension. It gives you autocomplete, type-checking and go-to-definition inside your templates, not just your TypeScript files.
- Angular DevTools — a Chrome/Edge extension that adds an "Angular" panel to DevTools, letting you inspect the live component tree, view signal/property values, and profile change detection.
Angular DevTools' component tree view is how you'll inspect signal values in Week 5, and its profiler is exactly what Week 20 (Performance) uses to find real bottlenecks.
7. Hands-on Exercise
Scaffold a multi-app workspace with a shared library
Build the structure from Section 4 for real, then wire the library into both apps.
Requirements:
- Create an empty workspace named
course-workspace(no default application). - Generate two applications:
adminandstorefront. - Generate a library named
ui-kit, and add one exported component to it (a simple button is fine) via itspublic-api.ts. - Import and render that component in the root component of both
adminandstorefront. - Confirm
ng serve adminandng serve storefrontboth run (on different ports) and both show the shared component. - Add an npm script to
package.jsonthat builds both applications in one command.
If the library import doesn't resolve, check tsconfig.json's paths entry — ng generate library should add it automatically, but it's worth confirming you can read what it wrote.
8. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
What's the practical difference between npx @angular/cli new and a global ng install?
What's the practical difference between npx @angular/cli new and a global ng install?
npx downloads and runs the latest CLI for that one command without installing anything permanently — useful for occasional use or trying a new major version. A global install (npm install -g) gives you the shorter ng command everywhere, but you're responsible for updating it yourself.
Q2
Which two tools does the @angular/build:application builder use, and for what?
Which two tools does the @angular/build:application builder use, and for what?
esbuild for production bundling (fast, minified output) and Vite for the dev server (fast cold starts and near-instant rebuilds during ng serve).
Q3
In a multi-app workspace, how does an app actually import code from a generated library?
In a multi-app workspace, how does an app actually import code from a generated library?
Via a TypeScript path mapping in tsconfig.json — ng generate library adds an entry under compilerOptions.paths pointing at the library's public-api.ts, so any app in the workspace can import { Thing } from 'ui-kit' without a published npm package.
Q4
How does fileReplacements let the same import path resolve to different values in dev vs. production?
How does fileReplacements let the same import path resolve to different values in dev vs. production?
angular.json's production configuration swaps environment.ts for environment.production.ts at build time, before bundling even starts. Your code always imports ./environments/environment — the builder decides which physical file that path resolves to, so there's no runtime branching or extra bundle weight.