Angular First App

Every generated Angular project shares the same predictable folder structure, anchored by a root component called AppComponent.

Anatomy of a Generated Project

Running ng new produces a folder full of configuration and a src/ directory holding your actual application code. Understanding this layout early makes every later topic - components, routing, services - easier to place mentally.

PathPurpose
src/main.tsEntry point; bootstraps the root component
src/index.htmlThe single HTML page the app is injected into
src/styles.cssGlobal styles shared across the whole app
src/app/app.component.tsThe root component's class and metadata
src/app/app.component.htmlThe root component's template
src/app/app.config.tsApplication-wide providers (router, HTTP client, etc.)
angular.jsonCLI configuration: build targets, assets, styles
package.jsonnpm dependencies and scripts

The Bootstrapping Process

main.ts is the very first file that runs. It calls bootstrapApplication, passing in the root component and any application-wide configuration. Angular then renders that root component into the <app-root></app-root> tag found in index.html.

src/main.ts

import { Component, ApplicationConfig } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

// In a real generated project, AppComponent lives in its own file at
// src/app/app.component.ts, and appConfig lives in its own file at
// src/app/app.config.ts. Both are inlined here so this example runs as a
// single, self-contained file.
@Component({
  selector: 'app-root',
  standalone: true,
  template: `<h1>{{ title }}</h1>`
})
export class AppComponent {
  title = 'my-first-app';
}

const appConfig: ApplicationConfig = {
  providers: []
};

bootstrapApplication(AppComponent, appConfig)
  .catch(err => console.error(err));

Inspecting app.component.ts

The root component is a completely ordinary component - there is nothing special about it besides being the one passed to bootstrapApplication. It typically imports RouterOutlet so routed pages can render inside it.

src/app/app.component.ts

import { Component } from '@angular/core';
import { RouterOutlet, provideRouter } from '@angular/router';
import { bootstrapApplication } from '@angular/platform-browser';

// In a real generated project the template and styles below live in their
// own files, app.component.html and app.component.css, referenced via
// templateUrl/styleUrl. They are inlined here so this example runs as a
// single, self-contained file.
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  template: `
    <header>
      <h1>{{ title }}</h1>
    </header>
    <main>
      <router-outlet></router-outlet>
    </main>
  `
})
export class AppComponent {
  title = 'my-first-app';
}

bootstrapApplication(AppComponent, {
  providers: [provideRouter([])]
}).catch(err => console.error(err));
Note: The imports array inside @Component is unique to standalone components. It lists every directive, component, or pipe the template needs - replacing the old requirement of declaring everything in an NgModule.
  • main.ts bootstraps the app and points to the root component
  • index.html contains the <app-root> element the app mounts into
  • app.component.ts/.html/.css together define the root component
  • app.config.ts centralizes providers like the router and HTTP client
  • angular.json tells the CLI how to build, serve, and test the project

src/app/app.component.html

import { Component } from '@angular/core';
import { RouterOutlet, provideRouter } from '@angular/router';
import { bootstrapApplication } from '@angular/platform-browser';

// This is the template normally found in src/app/app.component.html,
// wrapped here in its owning component so the markup can run standalone.
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  template: `
<header>
  <h1>{{ title }}</h1>
</header>

<main>
  <router-outlet></router-outlet>
</main>
  `
})
export class AppComponent {
  title = 'my-first-app';
}

bootstrapApplication(AppComponent, {
  providers: [provideRouter([])]
}).catch(err => console.error(err));
Note: Open angular.json once early on. Seeing where global styles, assets, and build budgets are configured demystifies a lot of 'magic' later, such as why a CSS file you added to styles.css appears on every page.

Exercise: Angular First App

In a standalone Angular app, what bootstraps the root component?