Angular v21 Released — Signal Forms, ARIA Components, AI Tools & More

Angular v21 — Tutorial: Signal Forms, Angular Aria, MCP & Zoneless (Hands-On)

Explainer Published: 18 November 2025 • Author: The DotNet Office

A short, practical tutorial showing how to get started with the main Angular v21 features and small working examples you can paste into your project.

What you'll learn

  • How to scaffold a new Angular v21 project (commands)
  • A Signal Forms login form example
  • Using an Angular Aria combobox (headless accessible UI)
  • How to use the MCP server in read-only mode
  • Notes on zoneless apps and Vitest

Prerequisites

Make sure you have:

  • Node.js (>= 18 recommended)
  • npm or yarn
  • Angular CLI (latest)
  • Basic TypeScript and Angular knowledge

Note: Replace `ng` commands with your preferred package manager if needed (npm/yarn).

1) Create a new Angular v21 project

Scaffold a fresh app (the CLI will create a project configured for v21 defaults):

npx @angular/cli@latest new angular-v21-demo
cd angular-v21-demo
npm install

If you already have an app, use ng update to migrate to v21.

2) Signal Forms — Example: Login form

Signal Forms let you manage form state with signals instead of FormGroup. Here's a minimal login form using the new API (example is simplified).

Install (if needed) — the forms signals API is provided from Angular forms package:

npm install @angular/forms

login.component.ts

import { Component } from '@angular/core';
import { signal } from '@angular/core';
import { form, Field } from '@angular/forms/signals';

@Component({
  standalone: true,
  selector: 'app-login',
  imports: [Field],
  templateUrl: './login.component.html'
})
export class LoginComponent {
  // simple reactive model as a signal
  model = signal({ email: '', password: '' });

  // create a Signal Form instance bound to the model
  loginForm = form(this.model);

  onSubmit() {
    // loginForm.value() or access model()
    console.log('Submitting', this.model());
    // send to server, show validation, etc.
  }
}

login.component.html

<form (ngSubmit)="onSubmit()" >
  <label>Email</label>
  <input [field]="loginForm.email" type="email" />

  <label>Password</label>
  <input [field]="loginForm.password" type="password" />

  <button type="submit">Sign in</button>
</form>

This approach reduces boilerplate and integrates validation in a predictable, type-safe way. For custom controls, signal bindings avoid many previous complexities around ControlValueAccessor.

3) Angular Aria — Example: Accessible Combobox

Angular Aria provides headless (unstyled) primitives built with ARIA and keyboard interactions in mind. Install and use them as primitives for your custom UI.

npm i @angular/aria

combobox.component.ts (simplified)

import { Component, signal } from '@angular/core';
/* pseudo-imports — follow official Aria docs for actual API names */
import { ComboboxDirective } from '@angular/aria';

@Component({
  standalone: true,
  selector: 'app-combobox',
  template: `
    <div aria-label="Country selector">
      <input [ariaCombobox]="items" [value]="query()" (input)="onInput($event)" />
      <ul role="listbox">
        <li *ngFor="let it of filteredItems()" role="option">{{ it }}</li>
      </ul>
    </div>
  `
})
export class ComboboxComponent {
  query = signal('');
  items = ['India','United States','Canada','Australia','Germany'];
  filteredItems = () => this.items.filter(i => i.toLowerCase().includes(this.query().toLowerCase()));

  onInput(e: Event) {
    const v = (e.target as HTMLInputElement).value;
    this.query.set(v);
  }
}

Angular Aria ensures keyboard navigation, focus management and ARIA attributes are correct — you only style it to match your UI.

4) MCP Server — quick read-only example

The Model Context Protocol (MCP) server allows LLM agents to query your workspace. Run it in a safe read-only mode while experimenting:

# Start the MCP server in read-only mode (CLI)
ng mcp --read-only

An AI agent connected to MCP can query project structure, docs, or suggest migration steps. Keep the server in read-only for safety when experimenting.

5) Zoneless apps & Enabling zones (if needed)

By default v21 new projects are zoneless — Angular relies on Signals + explicit update triggers. This yields smaller bundles and more predictable rendering.

If you need Zone-based detection temporarily, add the provider:

import { provideZoneChangeDetection } from '@angular/core';

bootstrapApplication(App, {
  providers: [ provideZoneChangeDetection() ]
});

Use migration schematics for large apps rather than flipping the provider manually across many modules.

6) Quick: Vitest example (test a service)

Angular v21 defaults to Vitest for new projects. Minimal example test for a simple service:

// greeting.service.ts
export class GreetingService {
  greet(name: string) { return `Hello, ${name}`; }
}

// greeting.spec.ts (Vitest)
import { describe, it, expect } from 'vitest';
import { GreetingService } from './greeting.service';

describe('GreetingService', () => {
  it('returns greeting', () => {
    const svc = new GreetingService();
    expect(svc.greet('Alice')).toBe('Hello, Alice');
  });
});

Run tests with npm test or npx vitest depending on your setup.

7) Quick migration tips

  • Use ng update to apply official migration schematics.
  • Try Signal Forms and Aria in a feature branch or isolated module first.
  • Use the MCP tool onpush_zoneless_migration to generate migration suggestions.
  • Migrate tests to Vitest using the provided refactor schematic.

Final notes

Angular v21 is focused on modern reactive patterns, accessibility primitives, and AI-enhanced development workflows. Start small: adopt Signal Forms and Aria in a feature module, use MCP read-only to discover how AI can help your codebase, and migrate tests to Vitest for a faster developer experience.

If you'd like, I can:

  • Convert any of the above examples into a downloadable StackBlitz-ready project
  • Write a full migration checklist for a production app
  • Create SEO-tailored headings and meta tags specifically for your Blogger theme

Share this

Related Posts

Latest
Previous
Next Post »