Welcome to the Future of Angular!

Hello, aspiring Angular developer! Get ready to embark on an exciting journey into the world of modern Angular. In this learning guide, we’re going to dive deep into building robust, scalable, and maintainable applications using the latest Angular architecture. Our focus will be exclusively on Standalone Angular, which streamlines development by removing the need for NgModules. This approach makes your applications lighter, more modular, and easier to reason about.

This first chapter is all about laying a solid foundation. We’ll start from square one, guiding you through setting up your development environment, understanding the core principles of standalone components, and creating your very first Angular application. By the end of this chapter, you’ll have a running Angular project and a clear understanding of how standalone components simplify application structure. Ready to build something awesome? Let’s go!

Prerequisites

Since this is our starting point, we assume you have a basic understanding of web development concepts like HTML, CSS, and JavaScript/TypeScript. Familiarity with the command line (terminal) will also be very helpful. No prior Angular experience is required, as we’ll cover everything from the ground up!


Core Concepts: Embracing Standalone Angular

Before we jump into code, let’s understand why Standalone Angular is such a game-changer and what fundamental ideas underpin it.

What are Standalone Components, Directives, and Pipes?

Imagine you’re building with LEGOs. Traditionally, in Angular, you’d put a bunch of related LEGO blocks (components, directives, pipes) into a bigger box called an NgModule. Then, if another part of your application wanted to use those blocks, it would import the whole box. While this worked, sometimes you only needed one or two blocks from the box, but you still had to carry the whole thing around.

Standalone components, directives, and pipes are like individual, self-contained LEGO blocks. They declare their own dependencies directly. If a component needs a specific button component, an input directive, or a date pipe, it simply imports only what it needs, right there in its own definition. No more NgModule boxes!

Why Standalone?

  1. Simplicity: Less boilerplate code. You don’t need to declare components in a module, export them, and then import the module elsewhere. It’s just: define it, import it.
  2. Modularity: Components become truly self-contained. This makes them easier to reuse, test, and understand in isolation.
  3. Performance: The Angular build system can better “tree-shake” your application. This means it can remove unused code more efficiently, leading to smaller bundle sizes and faster load times.
  4. Future-Proof: Standalone components are the recommended and default way to build Angular applications moving forward.

The Problem Standalone Solves

Before standalone, NgModules were a central organizing principle. While powerful, they often led to:

  • Boilerplate: Every component, directive, and pipe had to be declared in exactly one NgModule. Services were often provided via modules as well.
  • “Barrel Files” Complexity: Large applications could end up with many NgModules and complex import structures.
  • Circular Dependencies: Sometimes, NgModules could inadvertently create circular dependencies, making debugging tricky.
  • Learning Curve: For newcomers, understanding NgModules, declarations, imports, exports, and providers arrays was a significant hurdle.

Standalone architecture simplifies this by allowing components, directives, and pipes to be directly imported where they are used, similar to how you import functions or classes in JavaScript.

Setting Up Your Angular Development Environment

To build Angular applications, you’ll need a few tools on your machine. Think of these as your workshop tools!

1. Node.js and npm (or Yarn)

Angular applications are built using JavaScript and TypeScript, which run on Node.js. npm (Node Package Manager) or Yarn is used to manage project dependencies.

  • Node.js: As of early 2026, the latest LTS (Long Term Support) versions of Node.js are likely v20.x or v22.x. It’s always a good idea to use an LTS version for stability.
    • How to install: Visit the official Node.js website (nodejs.org) and download the recommended LTS version for your operating system.
    • Verification: Open your terminal or command prompt and type:
      node -v
      npm -v
      
      You should see version numbers like v22.x.x and 11.x.x respectively.

2. Angular CLI (Command Line Interface)

The Angular CLI is a powerful tool that helps you create projects, generate code, run tests, and deploy applications. It automates many common development tasks.

  • How to install: Once Node.js and npm are installed, you can install the Angular CLI globally using npm:
    npm install -g @angular/cli@latest
    
    The @latest ensures you get the most recent stable version, which, as of 2026, would be around Angular CLI v21.x.x or v22.x.x.
  • Verification: In your terminal, type:
    ng version
    
    This command will display the versions of Angular CLI, Node.js, and other related packages.

Creating Your First Standalone Angular Project

Now that your tools are ready, let’s create a new Angular application. Remember, we’re going straight for the standalone approach!

The Angular CLI has made standalone the default for new projects. If you’re on a very recent CLI version (e.g., v17+), you might not even need the --standalone flag, but it’s good practice to include it for clarity or if your CLI is slightly older.

ng new my-first-standalone-app --standalone --routing --style=scss

Let’s break down this command:

  • ng new: This command tells the Angular CLI to create a new Angular workspace and application.
  • my-first-standalone-app: This is the name of your new application. Feel free to choose your own!
  • --standalone: This is the critical flag! It instructs the CLI to generate an application that uses standalone components by default, skipping the generation of NgModules.
  • --routing: This adds an AppRoutingModule (as a standalone file, not an NgModule) to handle navigation within your application. We’ll explore routing in future chapters.
  • --style=scss: This sets the default stylesheet format to SCSS, which offers powerful features like variables and mixins. You can choose css, less, or sass if you prefer.

After running the command, the CLI will ask you a few questions (e.g., “Would you like to share anonymous usage data with the Angular Team?”). Answer y or n as you wish. Then, it will create all the necessary files and install the npm packages. This might take a few minutes.

Once it’s done, navigate into your new project folder:

cd my-first-standalone-app

Understanding the Modern Standalone Project Structure

Let’s take a quick tour of the generated project. Open the my-first-standalone-app folder in your favorite code editor (like VS Code).

Here’s a simplified view of the key files and folders you’ll see:

my-first-standalone-app/
├── src/
│   ├── app/
│   │   ├── app.component.ts        // The root standalone component
│   │   ├── app.component.html      // Template for the root component
│   │   ├── app.component.scss      // Styles for the root component
│   │   ├── app.config.ts           // Application-wide configuration (providers, routes)
│   │   └── app.routes.ts           // Defines application routes
│   ├── assets/                     // Static assets (images, icons)
│   ├── environments/               // Environment-specific configurations
│   ├── main.ts                     // The application's entry point
│   ├── index.html                  // The main HTML page served by the browser
│   └── styles.scss                 // Global styles
├── angular.json                    // Angular workspace configuration
├── package.json                    // Project dependencies and scripts
└── tsconfig.json                   // TypeScript configuration

Notice a few things:

  • There’s no app.module.ts! This is the most significant change.
  • The app folder directly contains app.component.ts, app.config.ts, and app.routes.ts. These files now handle what app.module.ts used to do.

The main.ts Entry Point and bootstrapApplication

The main.ts file is the very first TypeScript file that gets executed when your Angular application starts. With standalone architecture, it’s remarkably simple:

// src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, appConfig)
  .catch((err) => console.error(err));
  • import { bootstrapApplication } from '@angular/platform-browser';: This function is responsible for bootstrapping (starting) your Angular application. It’s the replacement for platformBrowserDynamic().bootstrapModule(AppModule).
  • bootstrapApplication(AppComponent, appConfig):
    • AppComponent: This is the root component of your application. It’s the first component Angular loads and renders.
    • appConfig: This object, defined in app.config.ts, provides application-wide configurations, such as global providers (services) and the routing configuration.

This main.ts file elegantly demonstrates the standalone philosophy: directly bootstrap your root component and provide its configuration, without any intermediary modules.

The app.config.ts File

This file is central to configuring your standalone application. It consolidates application-wide providers and features.

// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes'; // Our application routes

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes) // Registers the router and our defined routes
  ]
};
  • ApplicationConfig: This interface from @angular/core defines the structure for application configuration.
  • providers: This array is where you’ll register global services and feature providers. Here, provideRouter(routes) is crucial for enabling Angular’s routing capabilities.

Running Your Application

Let’s see your new application in action! In your terminal, inside the my-first-standalone-app directory, run:

ng serve

This command compiles your application and launches a development server. Once it’s ready, open your web browser and navigate to http://localhost:4200/. You should see the default Angular welcome page!


Step-by-Step Implementation: Building with Standalone Components

Now that we have our project running, let’s get our hands dirty by creating and using our own standalone component.

Step 1: Examine the Root Standalone Component (AppComponent)

Open src/app/app.component.ts. You’ll see something like this:

// src/app/app.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common'; // Needed for common directives like ngIf, ngFor
import { RouterOutlet } from '@angular/router'; // Needed for routing

@Component({
  selector: 'app-root',
  standalone: true, // THIS is the key!
  imports: [CommonModule, RouterOutlet], // Import dependencies directly
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})
export class AppComponent {
  title = 'my-first-standalone-app';
}

Explanation:

  • @Component: This is the decorator that marks this class as an Angular component.
  • selector: 'app-root': This defines the HTML tag (<app-root>) that you’ll use to embed this component in index.html.
  • standalone: true: This is the magic! It tells Angular that this component is self-contained and doesn’t belong to any NgModule.
  • imports: [CommonModule, RouterOutlet]: This is where a standalone component declares its own dependencies.
    • CommonModule: Provides common Angular directives like *ngIf, *ngFor, ngClass, etc. Without it, you couldn’t use these in your component’s template.
    • RouterOutlet: This is a directive from Angular’s router that marks where routed components should be displayed.
  • templateUrl and styleUrl: Point to the component’s HTML template and CSS styles.
  • export class AppComponent: This is the TypeScript class where your component’s logic resides.

Step 2: Create a New Standalone Component

Let’s create a simple “Greeting” component. We’ll use the Angular CLI for this:

In your terminal (still inside my-first-standalone-app), run:

ng generate component greeting --standalone

Or, the shorthand:

ng g c greeting --standalone

The CLI will create a greeting folder inside src/app/ with four files:

  • greeting.component.ts
  • greeting.component.html
  • greeting.component.scss
  • greeting.component.spec.ts (for testing)

Open src/app/greeting/greeting.component.ts. It should look similar to app.component.ts:

// src/app/greeting/greeting.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common'; // Often included by default for basic templates

@Component({
  selector: 'app-greeting',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './greeting.component.html',
  styleUrl: './greeting.component.scss'
})
export class GreetingComponent {
  name = 'Developer'; // Let's add a property to display
}

Now, open src/app/greeting/greeting.component.html and add some content:

<!-- src/app/greeting/greeting.component.html -->
<p>
  Hello, {{ name }}! Welcome to your standalone Angular app.
</p>

Step 3: Use Your New Standalone Component

To display GreetingComponent, we need to import it into AppComponent and then use its selector in AppComponent’s template.

First, open src/app/app.component.ts and add GreetingComponent to its imports array:

// src/app/app.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { GreetingComponent } from './greeting/greeting.component'; // <--- NEW IMPORT

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    CommonModule,
    RouterOutlet,
    GreetingComponent // <--- Add your new component here
  ],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})
export class AppComponent {
  title = 'my-first-standalone-app';
}

Next, open src/app/app.component.html and replace its content with something simpler, including your new app-greeting component:

<!-- src/app/app.component.html -->
<main>
  <h1>{{ title }}</h1>
  <app-greeting></app-greeting> <!-- <--- Use your component's selector here -->
  <router-outlet></router-outlet>
</main>

Save all files. Your browser, which is still running ng serve, should automatically refresh. You should now see:

my-first-standalone-app
Hello, Developer! Welcome to your standalone Angular app.

Congratulations! You’ve successfully created and integrated your first standalone component. Notice how direct and clear the import statement is within app.component.ts? That’s the power of standalone architecture!

Step 4: Passing Data to a Standalone Component with @Input()

Components are most useful when they can receive data. Let’s make our GreetingComponent more dynamic by allowing AppComponent to pass the name.

First, modify src/app/greeting/greeting.component.ts to accept an input:

// src/app/greeting/greeting.component.ts
import { Component, Input } from '@angular/core'; // <--- Import Input
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-greeting',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './greeting.component.html',
  styleUrl: './greeting.component.scss'
})
export class GreetingComponent {
  @Input() name: string = 'Guest'; // <--- Define an input property with a default value
}

Explanation:

  • @Input(): This decorator marks the name property as an input property. This means other components can bind data to it using property binding ([]).
  • name: string = 'Guest': We declare name as a string and give it a default value of ‘Guest’. This is a good practice for optional inputs.

Now, modify src/app/app.component.html to pass a value to the name input:

<!-- src/app/app.component.html -->
<main>
  <h1>{{ title }}</h1>
  <!-- Pass the 'name' property from AppComponent to GreetingComponent -->
  <app-greeting [name]="'Alice'"></app-greeting>
  <app-greeting [name]="'Bob'"></app-greeting>
  <router-outlet></router-outlet>
</main>

Save and observe the browser. You should now see greetings for “Alice” and “Bob”!

my-first-standalone-app
Hello, Alice! Welcome to your standalone Angular app.
Hello, Bob! Welcome to your standalone Angular app.

This demonstrates how cleanly data flows between standalone components.

Diagram: Standalone Component Interaction

Let’s visualize this simple interaction:

flowchart TD A[index.html] --->|Bootstraps| B("main.ts") B --->|Starts Application with| C[AppComponent] C --->|Imports and uses| D[GreetingComponent] C --->|Imports and uses| E[GreetingComponent] D --->|Displays Hello Alice| F{Browser DOM} E --->|Displays Hello Bob| F

Explanation:

  1. The index.html file is the entry point, loading the Angular application.
  2. main.ts is executed, which bootstrapApplications AppComponent.
  3. AppComponent is a standalone component. It explicitly imports GreetingComponent.
  4. AppComponent’s template (app.component.html) uses the <app-greeting> selector twice, passing different name values via @Input().
  5. Each GreetingComponent instance renders its own message in the browser’s Document Object Model (DOM).

Mini-Challenge: Build a Simple User Card Component

Your turn! Let’s solidify your understanding.

Challenge: Create a new standalone component called user-card. This component should:

  1. Be standalone (standalone: true).
  2. Accept two @Input() properties: userName (string) and userEmail (string).
  3. Display these properties in its template in a visually appealing way (e.g., inside a <div> with <p> tags).
  4. Import and use this user-card component twice in app.component.html, passing different userName and userEmail values for each instance.

Hint: Remember the ng generate component command and how we added @Input() to GreetingComponent. Don’t forget to import CommonModule if you plan to use any basic Angular directives in your user-card’s template.

What to Observe/Learn:

  • How easily you can create new standalone components.
  • The clear import mechanism in imports: [].
  • The power of @Input() for component reusability.

Common Pitfalls & Troubleshooting

Even with simplified standalone components, it’s easy to stumble on a few common issues.

  1. “Component is not a known element” Error:

    • Problem: This is the classic error when you forget to make a component available. In standalone Angular, it means you likely forgot to add your component to the imports array of the parent component where you’re trying to use it.
    • Solution: Double-check the imports array in the @Component decorator of the component that is trying to use the unknown component. For example, if AppComponent uses UserCardComponent, UserCardComponent must be in AppComponent’s imports array.
    • Example:
      // app.component.ts (missing UserCardComponent in imports)
      @Component({
        selector: 'app-root',
        standalone: true,
        imports: [CommonModule, RouterOutlet], // Oops, forgot UserCardComponent!
        template: '<app-user-card></app-user-card>' // This will fail!
      })
      export class AppComponent { /* ... */ }
      
  2. Missing CommonModule:

    • Problem: You’re trying to use *ngIf, *ngFor, ngClass, ngStyle, or other common structural/attribute directives in your component’s template, but they don’t seem to work, or you get template parsing errors.
    • Solution: Ensure CommonModule is included in the imports array of your standalone component. The CLI usually adds it by default, but it’s good to be aware.
    • Example:
      // my-list.component.ts (missing CommonModule)
      @Component({
        selector: 'app-my-list',
        standalone: true,
        // imports: [], // Oops, forgot CommonModule!
        template: `
          <div *ngFor="let item of items">{{ item }}</div>
        `
      })
      export class MyListComponent { items = ['A', 'B']; }
      
  3. Angular CLI Version Mismatch:

    • Problem: You’re trying to use a command like ng new --standalone but your CLI is an older version that doesn’t support it, or you’re running into unexpected build issues.
    • Solution: Always ensure your global Angular CLI version is up-to-date with your project’s Angular version. Use npm install -g @angular/cli@latest to update your global CLI. Then, check your project’s local CLI version with ng version inside your project directory. If your project is older, ng update can help migrate it.

When troubleshooting, always check your browser’s developer console for error messages – they are your best friends!


Summary: What We’ve Learned

In this foundational chapter, we’ve taken our first crucial steps into the world of modern Standalone Angular:

  • Understanding Standalone: We explored why standalone components exist, the problems they solve (like NgModule boilerplate), and how they simplify application architecture.
  • Environment Setup: You’ve successfully installed Node.js, npm, and the Angular CLI, preparing your development environment.
  • Project Creation: You initiated a new Angular project using the --standalone flag, embracing the latest recommended architecture.
  • Core Structure: You learned about the new project layout, particularly the absence of NgModules and the roles of main.ts, app.config.ts, and app.component.ts.
  • bootstrapApplication: We demystified the main.ts entry point and the bootstrapApplication function, which now starts your Angular app directly with AppComponent.
  • Component Creation & Usage: You created your own standalone GreetingComponent, understood the standalone: true flag, and learned how to import and use it in another component’s template.
  • Data Flow with @Input(): You implemented data passing between components using the @Input() decorator, a fundamental concept for building reusable UI elements.
  • Troubleshooting: We covered common pitfalls like missing component imports and CommonModule, equipping you to debug initial issues.

You now have a solid understanding of how to set up and start building with Standalone Angular. This modular, simpler approach will serve as the bedrock for all the advanced topics we’ll cover in future chapters.

What’s Next?

In the next chapter, we’ll dive deeper into Angular’s powerful data binding mechanisms, exploring more ways components communicate, and introduce the concept of services for managing application logic and data across components. Get ready to make your applications even more interactive!


References


This page is AI-assisted and reviewed. It references official documentation and recognized resources where relevant.