Project Structure & Bootstrapping
A new Angular project contains about twenty files, and it is easy to feel lost. Most of them are configuration you rarely touch. In this lesson you will learn which files matter, how the app starts in the browser (this is called bootstrapping), and where your own code goes.
The project folder
Here is the layout of the canteen project created in the previous lesson:
canteen/
angular.json workspace and build settings
package.json npm packages and scripts
tsconfig.json TypeScript settings (plus tsconfig.app.json, tsconfig.spec.json)
public/ static files copied as-is (favicon.ico, images)
node_modules/ downloaded packages (never edit, never commit)
src/
index.html the single HTML page
main.ts the entry point that starts Angular
styles.css global styles for the whole app
app/
app.ts the root component class
app.html the root component template
app.css the root component styles
app.spec.ts tests for the root component
app.config.ts application-wide providers
app.routes.ts the list of routes (URLs)You will spend almost all your time inside src/app. Global CSS such as fonts and body colours go in src/styles.css. Images that you refer to by URL, such as /logo.svg, go in public/.
| File | Edit it? | Why |
|---|---|---|
src/app/* | Yes, all the time | Your components, services and routes |
src/styles.css | Sometimes | Global styles |
angular.json | Rarely | Build options, budgets, extra global styles |
package.json | Through npm | Add packages with npm install or ng add |
node_modules/ | Never | Recreated by npm install |
How the app starts
When the browser opens your app, four files work together, in this order.
1. src/index.html is the only HTML page. Its body contains one custom tag:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Canteen</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<app-root></app-root>
</body>
</html><app-root> is empty at first. Angular will fill it with the root component. The <base href="/"> tag tells the router where the app's URLs begin.
2. src/main.ts is the entry point. The build tool starts here and follows every import:
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { App } from './app/app';
bootstrapApplication(App, appConfig).catch((err) => console.error(err));bootstrapApplication creates the application, applies the configuration and renders the App component into the element that matches its selector, <app-root>.
3. src/app/app.config.ts lists providers: services and features that the whole app can use.
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideBrowserGlobalErrorListeners(),
provideRouter(routes),
],
};provideBrowserGlobalErrorListeners() makes Angular report uncaught errors in the browser, and provideRouter(routes) turns on routing. Later you will add more here, such as provideHttpClient() for calling APIs.
4. src/app/app.ts is the root component, the top of your component tree. Every other component appears inside it.
import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
templateUrl: './app.html',
styleUrl: './app.css',
})
export class App {
protected readonly title = signal('Canteen');
}The template lives in a separate file, app.html, and the styles in app.css. imports: [RouterOutlet] lets the template use <router-outlet />, the place where routed pages appear.
Replace the welcome page
The generated app.html is a long welcome page. Delete everything in it and write your own content:
<header>
<h1>{{ title() }} - Sharma Ji's College Canteen</h1>
<p>Order before 12:30 pm for lunch pickup.</p>
</header>
<router-outlet />Save the file while ng serve is running and the browser shows:
Canteen - Sharma Ji's College Canteen Order before 12:30 pm for lunch pickup.
{{ title() }} reads the title signal from the class. The protected keyword means the template can use it but other classes cannot, which keeps the component's public surface small.
Inside angular.json
angular.json describes the workspace: one or more projects and how to build, serve and test them. A few settings are worth knowing:
"browser": "src/main.ts"is the entry point."assets"copies everything inpublic/into the build."styles": ["src/styles.css"]lists global stylesheets. Add a library's CSS file here if it needs one."budgets"makes the production build warn or fail if your bundle grows too large (by default it warns at 500 kB and fails at 1 MB for the initial bundle).
A workspace can hold several apps and libraries; extra ones are created in the projects/ folder with ng generate application or ng generate library.
Common mistakes
- Removing
<app-root>fromindex.html. Angular then has nowhere to render, and the page stays blank with an error in the console about the selector not matching any element. - Putting images in
src/instead ofpublic/. Files outside the configured assets are not copied to the build, so the image shows as broken. - Editing files in
node_modules. Your changes disappear on the nextnpm install. Configure things in your own code instead. - Committing
node_modulesordist. The generated.gitignorealready excludes them; keep it that way.
Key points
- Your code lives in
src/app; global styles go insrc/styles.css; static files go inpublic/. index.htmlcontains<app-root>, which Angular fills with the rootAppcomponent.main.tscallsbootstrapApplication(App, appConfig)to start the app.app.config.tslists app-wide providers such asprovideRouter(routes).angular.jsonholds build settings, assets, global styles and size budgets.
Exercise
In your canteen project, change the page title in index.html to "Campus Canteen", change the title signal to "Campus Canteen" and replace app.html with a heading and a paragraph giving the canteen's opening hours (8 am to 6 pm). Then add a global style in src/styles.css that sets the body font to system-ui and the margin to 0.
Show solution
export class App {
protected readonly title = signal('Campus Canteen');
}<h1>{{ title() }}</h1>
<p>Open daily from 8 am to 6 pm.</p>
<router-outlet />body {
margin: 0;
font-family: system-ui, sans-serif;
}The <title> in index.html changes the browser tab text, while the signal changes the heading inside the page. Global body styles belong in src/styles.css, not in app.css, because component styles only apply to that component's own template.
Quick Quiz
1. Which function starts a standalone Angular application in main.ts?
Standalone apps start with bootstrapApplication(App, appConfig).
2. Where do you register app-wide features such as the router?
app.config.ts exports the ApplicationConfig with the app-wide providers.
3. Where should a logo image that you link as /logo.svg go in a new project?
Everything in public/ is copied to the build output as-is.
Learn Angular with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
