Angular Project Structure

Read one Angular interview question at a time, then flip for the complete explanation, example, and code.

0/64 Known filtered set
Level
Read Full Guide Question: 1 of 64

Angular Interview Questions · Angular Project Structure Companion Article

Angular Project Structure

An Angular project contains application source code, configuration files, dependencies, static files, build settings, and environment-specific configuration. Understanding where these files are located and why Angular uses them makes development, debugging, deployment, and team collaboration much easier. A developer should not think of the Angular project structure as just a collection of folders: each important file participates in a particular stage of the application lifecycle, from installing dependencies and loading build configuration to bootstrapping the application and rendering it in the browser.

Angular Workspace

For example:

Text
package.json
    ↓
Dependencies installed
    ↓
angular.json
    ↓
Build configuration loaded
    ↓
main.ts
    ↓
Angular application bootstrapped
    ↓
Application configuration loaded
    ↓
Root component rendered
    ↓
index.html displays the application

An Angular workspace is the top-level directory in which Angular applications and libraries are developed.

When you create a project using:

Bash
ng new my-app

Angular CLI creates a workspace and normally creates the first Angular application inside that workspace.

A simplified workspace may look like this:

Text
my-app/
├── public/
├── src/
│   ├── app/
│   ├── index.html
│   ├── main.ts
│   └── styles.css
├── angular.json
├── package.json
├── package-lock.json
├── tsconfig.json
├── tsconfig.app.json
└── node_modules/

The workspace contains two major categories of files.

Application Files

These contain the actual application code.

Examples:

Text
src/
src/app/
src/main.ts
src/index.html
src/styles.css

Workspace Configuration Files

These control dependencies, compilation, builds, testing, and Angular CLI behavior.

Examples:

Text
angular.json
package.json
tsconfig.json

A workspace can contain a single Angular application or multiple applications and libraries.

For larger organizations, one workspace may contain:

Text
projects/
├── admin-portal/
├── customer-portal/
└── shared-ui/

This approach is useful when multiple Angular projects need to share common configuration or reusable libraries.

Understanding the src Folder

The src directory contains the source files used to build the Angular application.

A typical structure is:

Text
src/
├── app/
├── index.html
├── main.ts
└── styles.css

The app directory contains most of the Angular-specific application code.

As an application grows, developers usually organize the app folder according to features or responsibilities.

For example:

Text
src/app/
├── core/
├── shared/
├── features/
│   ├── products/
│   ├── orders/
│   └── users/
├── app.config.ts
├── app.routes.ts
└── root-component-files

There is no requirement that every application use exactly this organization. The best structure depends on the size and architecture of the application.

For a small application, keeping a few components directly under app/ may be reasonable.

For a large business application, grouping files by feature usually makes maintenance easier.

For example:

Text
features/
└── products/
    ├── components/
    ├── services/
    ├── models/
    └── product.routes.ts

This keeps product-related functionality together instead of scattering it across the entire project.

main.ts – Application Entry Point

main.ts is the main entry point of an Angular application.

It is one of the first application source files involved when Angular starts.

In a modern standalone Angular application, it commonly bootstraps the root application using bootstrapApplication().

Example:

TypeScript
import { bootstrapApplication } from '@angular/platform-browser';
import { App } from './app/app';
import { appConfig } from './app/app.config';

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

The basic startup flow is:

Text
Browser loads application
        ↓
main.ts executes
        ↓
bootstrapApplication() runs
        ↓
Application configuration is loaded
        ↓
Root component is created
        ↓
Angular renders the UI

Why main.ts Is Important

It acts as the bridge between the browser-loaded JavaScript application and Angular.

Developers normally keep this file small.

Business logic should generally not be placed inside main.ts.

Instead, its primary responsibility should be application startup.

index.html – Browser Host Page

index.html is the main HTML document used to host the Angular application.

A simplified version may look like:

HTML
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>My Angular App</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <app-root></app-root>
</body>
</html>

The important part is the root element:

HTML
<app-root></app-root>

Angular finds the root component associated with this selector and renders the application inside it.

Angular Does Not Work Like a Traditional Multi-Page Website

In a traditional website, different URLs may load completely different HTML files.

An Angular Single Page Application generally starts with one main HTML document and changes the displayed views using Angular components and routing.

For example:

Text
/index.html
     ↓
Angular starts
     ↓
/home
/products
/products/25
/cart
/profile

These routes can display different Angular components without requiring a completely separate HTML document for every view.

Should JavaScript Bundles Be Added Manually?

Normally, no.

The Angular build process handles the generated JavaScript and stylesheet bundles for the application.

Developers therefore usually do not manually add generated Angular bundle files using <script> tags inside index.html.

The Importance of <base href="/">

Angular applications commonly contain:

HTML
<base href="/">

The base URL helps Angular and the browser resolve relative URLs.

It becomes particularly important when the application uses Angular Router.

If an application is deployed under a subdirectory such as:

Text
https://example.com/customer/

the deployment configuration may need to account for that base path.

Incorrect base URL configuration can lead to problems such as:

Text
Page refresh returns 404
Assets fail to load
Router links behave incorrectly

Deployment URL configuration should therefore be tested separately from local development.

styles.css – Global Application Styles

styles.css contains styles that apply globally across the application.

Example:

CSS
html,
body {
  margin: 0;
  padding: 0;
  font-family: Arial, sans-serif;
}

body {
  background: #f5f5f5;
}

Global styles are suitable for things such as:

  • CSS resets
  • typography
  • theme variables
  • application-wide spacing rules
  • utility classes
  • third-party global styles

Angular components can also have their own styles.

Conceptually:

Text
styles.css
    ↓
Application-wide styles

Component stylesheet
    ↓
Styles related to a specific component

Global vs Component Styles

Suppose an application contains a reusable product card.

General page typography may belong in:

Text
src/styles.css

Product-card-specific styling should normally stay with the product card component.

This prevents one large stylesheet from becoming responsible for every visual element in the application.

angular.json – Angular Workspace Configuration

angular.json is one of the most important configuration files in an Angular CLI workspace.

It defines workspace-level and project-level settings used by Angular development and build tools.

A simplified structure looks like:

JSON
{
  "version": 1,
  "projects": {
    "my-app": {
      "projectType": "application",
      "sourceRoot": "src",
      "architect": {
        "build": {},
        "serve": {},
        "test": {}
      }
    }
  }
}

The actual generated file contains additional configuration.

What Can angular.json Control?

It can define settings related to:

  • application builds
  • development server
  • testing
  • project source root
  • styles
  • scripts
  • static assets
  • output paths
  • build configurations
  • optimization
  • source maps
  • file replacements
  • application budgets

For example, Angular may have different build settings for:

Text
development
production
staging

Build Targets in angular.json

Angular CLI commands often correspond to configured targets.

For example:

Bash
ng build

uses the application's build target.

Bash
ng serve

uses the application's development-server configuration.

Conceptually:

Text
Angular CLI command
        ↓
angular.json
        ↓
Target configuration
        ↓
Angular builder
        ↓
Task executed

This is why changing certain values inside angular.json can affect how ng build or ng serve behaves.

Production and Development Configurations

Applications frequently need different build behavior in development and production.

Development may prioritize:

Text
Debugging
Readable stack traces
Source maps
Fast rebuilds

Production may prioritize:

Text
Optimized bundles
Smaller output
Performance
Deployment readiness

Angular allows named configurations to be defined for build targets.

A configuration can then be selected using a command such as:

Bash
ng build --configuration production

Custom configurations can also be created when necessary.

For example:

Bash
ng build --configuration staging

This is useful when an organization has separate development, testing, staging, and production systems.

package.json – Dependencies and npm Scripts

package.json describes the Node/npm side of the Angular workspace.

It contains information about packages required by the project.

A simplified example is:

JSON
{
  "scripts": {
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test"
  },
  "dependencies": {
    "@angular/core": "...",
    "@angular/common": "...",
    "@angular/router": "..."
  },
  "devDependencies": {
    "@angular/cli": "...",
    "typescript": "..."
  }
}

dependencies

Packages required by the application are listed as dependencies.

Examples can include:

Text
@angular/core
@angular/common
@angular/router

devDependencies

Development-related packages may appear under devDependencies.

Examples include tooling used during:

Text
Compilation
Development
Testing
Building

npm Scripts

The scripts section provides convenient commands.

For example:

JSON
"scripts": {
  "start": "ng serve",
  "build": "ng build"
}

You can then execute:

Bash
npm start

instead of manually typing:

Bash
ng serve

package.json vs package-lock.json

These files have different responsibilities.

package.json

Describes which dependencies the project requires.

Example:

JSON
"dependencies": {
  "@angular/core": "^22.0.0"
}

package-lock.json

Records the dependency tree and resolved package versions installed by npm.

It helps developers and deployment systems reproduce consistent installations.

A common mistake is treating package-lock.json as an unnecessary temporary file.

For npm-based projects, it is generally kept in version control.

What Is node_modules?

After running:

Bash
npm install

npm installs packages into:

Text
node_modules/

This directory may become very large because Angular itself and its tooling depend on many npm packages.

Developers normally do not manually edit files inside node_modules.

They also normally do not commit the entire directory to Git.

Instead, another developer can restore the dependencies using:

Bash
npm install

based on the dependency information stored in the project's npm configuration files.

tsconfig.json – TypeScript Configuration

Angular applications are primarily written using TypeScript.

tsconfig.json provides the base TypeScript configuration used within the workspace.

A simplified example could contain:

JSON
{
  "compilerOptions": {
    "strict": true,
    "target": "ES2022"
  }
}

The exact configuration depends on the Angular and TypeScript versions used by the project.

What Can TypeScript Configuration Control?

Examples include:

  • strict type checking
  • JavaScript target
  • module behavior
  • library definitions
  • path mappings
  • compiler behavior

Angular projects may also contain additional TypeScript configuration files such as:

Text
tsconfig.app.json
tsconfig.spec.json

These files serve different compilation contexts.

Conceptually:

Text
tsconfig.json
      ↓
Base TypeScript configuration
      ↓
 ┌───────────────┬─────────────────┐
 ↓               ↓
tsconfig.app.json  tsconfig.spec.json
Application code   Test code

This separation allows different TypeScript settings to be applied where necessary.

Angular Compiler Configuration

Angular also has compiler-specific options.

These can appear under:

JSON
"angularCompilerOptions": {
}

Angular compiler configuration is different from normal TypeScript compiler configuration.

Conceptually:

Text
compilerOptions
      ↓
TypeScript compiler behavior

angularCompilerOptions
      ↓
Angular-specific compilation behavior

This distinction becomes useful when investigating template type checking or Angular compilation problems.

Application Configuration

Modern Angular applications commonly use standalone APIs.

In a standalone application, app.config.ts can contain application-wide providers.

Example:

TypeScript
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes)
  ]
};

This configuration is then passed when the application starts.

Example:

TypeScript
bootstrapApplication(App, appConfig);

What Can Application Configuration Contain?

Depending on application requirements, global providers may configure functionality such as:

Text
Routing
HTTP services
Animations
Application initialization
Dependency injection providers
Error handling
Other application-wide services

The idea is to keep application-wide setup in a predictable location instead of spreading startup configuration throughout unrelated components.

app.config.ts vs angular.json

These files may both contain "configuration," but their purposes are very different.

FileMain Responsibility
app.config.tsRuntime Angular application providers and setup
angular.jsonAngular CLI, build, serve, test, assets, and workspace configuration

For example:

Configuring Angular Router belongs to application configuration.

TypeScript
provideRouter(routes)

Configuring build output or global styles belongs to workspace/build configuration.

JSON
"styles": [
  "src/styles.css"
]

Remember this distinction:

Text
app.config.ts
= How the Angular application is assembled

angular.json
= How Angular tooling builds and manages the project

Standalone Angular vs Module-Based Angular

Modern Angular development commonly uses standalone APIs.

However, developers may still encounter existing applications based on Angular modules.

A standalone application may contain:

Text
app.config.ts
app.routes.ts

An older or intentionally module-based application may contain:

Text
app.module.ts
app-routing.module.ts

Therefore, finding app.module.ts in an Angular codebase does not automatically mean that the application is incorrect.

It usually means the project follows the NgModule architecture rather than the newer standalone approach.

This distinction is particularly important when joining an existing enterprise Angular project.

Assets and Public Files

Applications commonly need files that should be served without being processed as normal TypeScript application source.

Examples include:

Text
Images
Icons
JSON files
Documents
Static text files
Fonts
Robots files
Other static resources

Current Angular CLI projects provide a top-level:

Text
public/

directory for static files.

For example:

Text
public/
├── images/
│   └── logo.png
├── documents/
│   └── help.pdf
└── config/
    └── information.json

A file placed under the configured static asset directory can be copied to the build output without being treated like application TypeScript code.

public/ vs src/assets/

Developers working with different Angular versions may see different conventions.

Modern Angular CLI projects use:

Text
public/

as the default static public directory.

Many existing Angular projects use:

Text
src/assets/

and configure that location through angular.json.

Both patterns may therefore appear in real projects.

The important concept is not just the folder name. The important concept is understanding which folders are configured as build assets.

Angular build configuration can define which files and directories should be copied into the generated application.

This is especially useful when maintaining projects created with older Angular versions.

When to Use Static Assets

Static asset locations are suitable for content such as:

Text
logo.png
background.jpg
sample-data.json
manual.pdf
icons/

They are not normally the correct place for Angular components or TypeScript business logic.

For example:

Text
public/images/product.png

is appropriate.

But:

Text
public/product.service.ts

is not a sensible Angular application structure.

Application TypeScript code belongs under the Angular source structure.

Environment Configuration

Applications often connect to different systems depending on where they are running.

For example:

Text
Development API
Testing API
Staging API
Production API

Hard-coding those URLs throughout components creates maintenance problems.

Instead, Angular supports environment-specific build configuration.

Environment files can be generated using:

Bash
ng generate environments

A project may then contain:

Text
src/environments/
├── environment.ts
├── environment.development.ts
└── environment.staging.ts

Example production-oriented configuration:

TypeScript
export const environment = {
  production: true,
  apiUrl: 'https://api.example.com'
};

Development configuration:

TypeScript
export const environment = {
  production: false,
  apiUrl: 'http://localhost:8080'
};

Application code can import the environment configuration:

TypeScript
import { environment } from '../environments/environment';

console.log(environment.apiUrl);

Build configuration can determine which environment-specific file is used.

Environment File Replacement

Angular can use fileReplacements for environment-specific builds.

Conceptually:

Text
environment.ts
      ↓
Development build
      ↓
environment.development.ts used

environment.ts
      ↓
Production build
      ↓
Production configuration used

A development build might be executed with:

Bash
ng build --configuration development

A staging build could use:

Bash
ng build --configuration staging

This allows application source code to continue importing a consistent environment location while Angular substitutes the correct configuration during the build.

Never Store Secrets in Angular Environment Files

Environment files are useful for configuration, but they should not be treated as secure secret storage.

Do not place sensitive secrets such as:

Text
Database passwords
Private encryption keys
Service-account credentials
Server secrets
Private API credentials

inside Angular client-side source files.

Angular executes in the user's browser. Values bundled into browser JavaScript can potentially be inspected by users.

For example, this is unsafe:

TypeScript
export const environment = {
  databasePassword: 'my-secret-password'
};

A real secret should remain on a trusted backend or another appropriate secure system.

A frontend application should call the backend, and the backend should use protected credentials where required.

Think of Angular environment values as build-time client configuration, not a secret vault.

How Important Angular Files Work Together

Consider what happens when a developer executes:

Bash
npm start

A simplified process is:

Text
1. package.json
   Finds the "start" script

2. Angular CLI
   Executes the configured serve command

3. angular.json
   Provides project and development-server settings

4. TypeScript configuration
   Controls TypeScript compilation

5. main.ts
   Starts the Angular application

6. app.config.ts
   Provides application-wide configuration

7. Root component
   Creates the application's first Angular view

8. index.html
   Provides the browser document that hosts the application

9. styles.css
   Provides global application styles

10. public/
    Provides static resources

Understanding this relationship is more useful than memorizing individual filenames.

Build-Time Files vs Runtime Application Files

A useful way to understand Angular project structure is to divide files according to their responsibility.

Development and Build Configuration

Text
package.json
angular.json
tsconfig.json
tsconfig.app.json

These mainly influence dependency management, compilation, Angular CLI behavior, or builds.

Application Startup

Text
src/main.ts
src/app/app.config.ts

These participate in starting and configuring the Angular application.

Browser and UI Resources

Text
src/index.html
src/styles.css
src/app/
public/

These provide the host page, styling, components, templates, services, and static files.

This mental model makes unfamiliar Angular projects much easier to understand.

Practical Example: Adding Global CSS

Suppose every page should use the same box sizing.

Add the rule to:

Text
src/styles.css

Example:

CSS
* {
  box-sizing: border-box;
}

A style that belongs only to one feature component should usually stay with that component instead of being added globally.

Practical Example: Configuring an API URL

Suppose developers use:

Text
http://localhost:8080

while the deployed application uses:

Text
https://api.example.com

Instead of writing URLs directly inside every service, configure the appropriate environment values and use them from the service.

This makes deployment configuration easier to maintain.

Common Angular Project Structure Mistakes

Putting Everything Inside One Component

A small demonstration application may work with one component, but production applications quickly become difficult to maintain when routing, HTTP calls, UI logic, forms, and business rules all exist in the same file.

Separate functionality according to responsibility.

Editing node_modules

Changes made directly inside:

Text
node_modules/

can disappear after dependencies are reinstalled.

Application code should not depend on manually modified installed packages.

Hard-Coding Environment URLs

Avoid repeatedly writing:

TypeScript
const url = 'http://localhost:8080/api/users';

throughout services.

Use centralized configuration where appropriate.

Storing Secrets in Frontend Configuration

Anything delivered to the browser should be considered accessible to the client.

Do not assume that naming a variable secretKey or placing it in an environment file makes it private.

Mixing Global and Component Styles Without a Plan

Placing every CSS rule in styles.css can eventually create:

Text
Naming conflicts
Unexpected overrides
Large global stylesheets
Difficult maintenance

Use global styles for genuinely global concerns and component styles for feature-specific presentation.

Modifying angular.json Without Understanding the Build

Incorrect configuration can affect:

Text
ng serve
ng build
assets
styles
production builds
deployment output

When changing workspace configuration, understand which project and target the setting belongs to.

Assuming Every Angular Project Has the Same Structure

Angular projects differ depending on:

Text
Angular version
Standalone vs NgModule architecture
Single-project vs multi-project workspace
Testing setup
SSR requirements
Organization architecture
Custom build configuration

Therefore, developers should understand the purpose of the files instead of memorizing one exact directory tree.

Reading an Existing Angular Project

When joining an existing Angular project, inspect it in a logical order.

1. Check package.json

Understand:

Text
Angular version
Major dependencies
Available npm scripts
Development tools

2. Check angular.json

Understand:

Text
Project names
Build configuration
Serve configuration
Assets
Styles
Output configuration
Environment-specific builds

3. Check main.ts

Identify how the application is bootstrapped.

4. Check Application Configuration

Look for:

Text
app.config.ts

or, in module-based applications:

Text
app.module.ts

This helps identify the architectural style.

5. Check Routing

Look for files such as:

Text
app.routes.ts

This reveals the major application navigation structure.

6. Explore Feature Folders

Finally, move into actual application features such as:

Text
users/
products/
orders/
dashboard/
authentication/

This approach is much faster than opening files randomly.

Project Structure in Real Angular Applications

A maintainable business application may gradually evolve toward a structure similar to:

Text
src/
└── app/
    ├── core/
    │   ├── guards/
    │   ├── interceptors/
    │   └── services/
    ├── shared/
    │   ├── components/
    │   ├── directives/
    │   └── pipes/
    ├── features/
    │   ├── authentication/
    │   ├── dashboard/
    │   ├── products/
    │   └── orders/
    ├── app.config.ts
    └── app.routes.ts

This is an organizational strategy rather than a requirement imposed on every Angular application.

core

Often contains application-wide infrastructure.

Examples:

Text
Authentication services
HTTP interceptors
Route guards
Global services

shared

Often contains reusable UI or utility functionality.

Examples:

Text
Buttons
Loading indicators
Reusable pipes
Reusable directives
Common components

features

Contains business functionality.

Examples:

Text
Products
Orders
Customers
Payments
Reports

Feature-oriented organization becomes particularly valuable when multiple developers work on a large application.

Key Differences Between Important Files

File or FolderResponsibility
src/Main application source
main.tsStarts the Angular application
index.htmlBrowser host document
styles.cssGlobal styles
app.config.tsApplication-wide providers and runtime setup
angular.jsonAngular CLI and workspace/build configuration
package.jsonnpm dependencies and scripts
package-lock.jsonResolved npm dependency versions
tsconfig.jsonBase TypeScript configuration
tsconfig.app.jsonApplication-specific TypeScript configuration
public/Static public files
src/environments/Environment-specific client configuration when configured
node_modules/Installed npm packages

A Simple Way to Remember the Structure

Instead of memorizing filenames independently, associate each file with one question.

Text
Where is my application code?
→ src/

Where does Angular start?
→ main.ts

Which HTML page hosts the application?
→ index.html

Where are global styles?
→ styles.css

Where are application-wide Angular providers configured?
→ app.config.ts

How is the Angular workspace built and served?
→ angular.json

Which npm packages does the project need?
→ package.json

How should TypeScript compile the project?
→ tsconfig.json

Where should public static files go?
→ public/

How can build-specific client settings be handled?
→ environment configuration

Once these relationships are clear, navigating even a large Angular codebase becomes much easier.

Practical Takeaway

Angular project structure separates different responsibilities deliberately. Application logic belongs mainly under src/app, startup happens through main.ts, browser hosting begins with index.html, global styling belongs in styles.css, dependencies are managed through package.json, TypeScript behavior is controlled through TypeScript configuration, and Angular CLI build behavior is controlled through angular.json.

Modern Angular applications also separate application-level provider configuration through files such as app.config.ts, while static resources can be served through public/. Environment-specific build configuration can be used when development, staging, and production systems require different client settings.

The most useful skill is therefore not memorizing every generated filename. It is understanding which layer owns which responsibility and knowing where to investigate when something goes wrong.

Question Hint