Mark Thompson and Devin Chasanoff showcased agentic Angular applications, in which large language models interpret user requests and initiate UI updates or invoke functions—signifying a more profound connection between Angular and artificial intelligence. At the same time, the Angular team verified that Signal Forms will not be included in the Angular 20 release.

Agentic Angular Apps

Mark Thompson and Devin Chasanoff hosted two live streams that were entirely dedicated to writing code in real time.

Their goal was to show developers how to bring large language models straight into an Angular project, resulting in what they call an agentic Angular app.

With these agentic apps, the UI still collects user input exactly like any normal application. That input, however, is then sent directly as a prompt to an LLM. Whatever the model returns can alter the interface or even execute specific functions inside the app when it sees fit. The result is a far tighter connection between Angular and the capabilities of large language models.

Agentic Apps with Tools

The livestreams tackled distinct scenarios. In the first, a story generator was demonstrated: after a user typed in a concept, Angular took the LLM’s response and turned it into visual story cards that were rendered on screen.

For the second demo, they put together a storefront application that let the language model automatically narrow down product listings and place chosen items into the shopping cart, all driven by what the user wanted.

Q&A Session

In the Q&A session held last week with Angular team members Mark Thompson and Jeremy Elbourn, it was confirmed that Angular 20 has hit its feature freeze. Signal Forms, however, didn’t make the cut.

If your form’s data source is a Signal, you’ll still have to rely on the tried-and-true effect() function for pushing values into the FormGroup.

The session was pretty packed. Unlike their usual format with live coding, this one ran for 90 minutes of non-stop questions and answers. The main points were:

👉 Features in experimental or developer preview stages could still be dropped. It doesn’t happen often, but the possibility remains.
(Timestamp: 43:35)

👉 Jeremy shed light on why Angular Material has a smaller component set than other UI libraries.

Since Google relies on a monorepo across all its projects, Angular Material and the apps using it share the same codebase. Any change there becomes highly sensitive and pricey. Adding more components only increases the maintenance burden.

To ease that, the Angular team focuses on making custom component libraries built on Angular CDK as straightforward as possible.

(Timestamp: 55:30)

👉 Mark also gave a preview of a new documentation section that could have long-term effects. Can’t wait to see what that ends up being.

Vitest as experimental feature

Also, there’s movement on Vitest’s path to being officially supported in Angular. An experimental integration PR has just been merged.

GitHub logo feat(@angular/build): add experimental vitest unit-testing support #30130

When using the application build system via the @angular/build package (default for new projects starting in v20), a new experimental unit-test builder is available that initially uses vitest. This experimental system is intended to provide support for investigation of future unit testing efforts within the Angular CLI. As this is experimental, no SemVer guarantees are provided, the API and behavior may change, and there may be unexpected behavior. Available test runners may be added or removed as well.

The setup is somewhat different than the previous unit-testing builders. It uses a similar mechanism to that of the dev-server and requires a buildTarget option. This allows the code building aspects of the unit-testing process to leverage pre-existing option values that are already defined for development. If differing option values are required for testing, an additional build target configuration specifically for testing can be used.

The current vitest support has multiple caveats including but not limited to:

  • No watch support
  • jsdom based testing only (jsdom must be installed in the project)
  • Custom vitest configuration is not supported

An example configuration that would replace the test target for a project is as follows:

"test": {
    "builder": "@angular/build:unit-test",
    "options": {
        "tsConfig": "tsconfig.spec.json",
        "buildTarget": "::development",
        "runner": "vitest"
    }
}
Example of modified new app spec file
import { TestBed } from '@angular/core/testing';
import { App } from './app';
import { describe, test, beforeEach, afterEach, expect } from 'vitest';

describe('App', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [App],
    }).compileComponents();
  });

  afterEach(() => TestBed.resetTestingModule());

  test('should create the app', () => {
    const fixture = TestBed.createComponent(App);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });

  test(`should have the 'vitest-example' title`, () => {
    const fixture = TestBed.createComponent(App);
    const app = fixture.componentInstance;
    expect(app.title).toEqual('vitest-example');
  });

  test('should render title', () => {
    const fixture = TestBed.createComponent(App);
    fixture.detectChanges();
    const compiled = fixture.nativeElement as HTMLElement;
    expect(compiled.querySelector('h1')?.textContent).toContain('Hello, vitest-example');
  });
});

Detecting Memory Leaks

An educational clip on memory leaks comes from Dmytro Mezhenskyi of Decoded Frontend. He demonstrated via DevTools that a subscription left unsubscribed can still cling to a component instance — a scenario that frequently slips by unnoticed.