Skip to content

Commit 8a8e0e4

Browse files
ng20-en (#23)
Co-authored-by: Ferdinand Malcher <[email protected]>
1 parent 2369345 commit 8a8e0e4

File tree

2 files changed

+293
-0
lines changed

2 files changed

+293
-0
lines changed

blog/2025-05-angular20/README.md

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
---
2+
title: 'Angular 20 is here!'
3+
author: Angular Book Team
4+
5+
published: 2025-05-30
6+
lastModified: 2025-05-30
7+
keywords:
8+
- Angular
9+
- Angular 20
10+
- Structural Directives
11+
- vitest
12+
- Component Suffix
13+
language: en
14+
header: angular20.jpg
15+
---
16+
17+
Everything new comes in May - or at least a new major version of Angular:
18+
On **May 28, 2025**, **Angular 20** was released! You can find the release information directly from the Angular team in the official [Angular Blog](https://blog.angular.dev/announcing-angular-v20-b5c9c06cf301).
19+
20+
For migrating to Angular 20, we recommend using the `ng update` command.
21+
Detailed information on the required steps can be found in the [Angular Update Guide](https://angular.dev/update-guide).
22+
23+
> 🇩🇪 This article is available in German language here: [Angular 20 ist da!](https://angular-buch.com/blog/2025-05-angular20)
24+
25+
26+
## Versions of TypeScript and Node.js
27+
28+
For Angular 20, *at least* the following versions of TypeScript and Node.js are required:
29+
30+
- TypeScript: 5.8
31+
- Node.js: 20.19.x or higher, 22.12.x or higher, or 24.0.x or higher
32+
33+
Support for Node.js version 18 has been removed. You can find detailed information about supported versions in the [Angular documentation](https://angular.dev/reference/versions).
34+
35+
36+
## The new Coding Style Guide
37+
38+
Angular has evolved significantly in recent years, and many new concepts have been integrated into the framework.
39+
The Angular documentation was partially out of date: the Coding Style Guide, in particular, had no recommendations for the current status quo.
40+
This changed with Angular 20:
41+
The new [Style Guide](https://angular.dev/style-guide) has been heavily revised and streamlined.
42+
It includes current recommendations and best practices and serves as a guideline for development with current Angular versions.
43+
44+
### No more suffixes: more deliberate naming and new patterns
45+
46+
An important change worth mentioning concerns the suffixes in file and class names:
47+
The new Style Guide *no longer* recommends using suffixes for components, services, and directives.
48+
Starting with Angular 20, the CLI no longer generates suffixes like `.component.ts` or `.service.ts` by default.
49+
This new setting only applies to newly created projects.
50+
51+
The command `ng generate component book-card` thus produces the following output:
52+
53+
**up to Angular 19:**
54+
55+
```
56+
src/app
57+
book-card
58+
book-card.component.ts
59+
book-card.component.html
60+
book-card.component.scss
61+
book-card.component.spec.ts
62+
```
63+
64+
```ts
65+
// book-card.component.ts
66+
// ...
67+
@Component(/* ... */)
68+
export class BookCardComponent {}
69+
```
70+
71+
**starting with Angular 20:**
72+
73+
```
74+
src/app
75+
book-card
76+
book-card.ts
77+
book-card.html
78+
book-card.scss
79+
book-card.spec.ts
80+
```
81+
82+
```ts
83+
// book-card.ts
84+
// ...
85+
@Component(/* ... */)
86+
export class BookCard {}
87+
```
88+
89+
The goal: Angular applications should contain less boilerplate, and we should think more deliberately about naming abstractions.
90+
Instead of automatically generated constructs like `product-detail.component.ts`, we're now expected to think: What is this class called? What does it do? How much does the name say on its own?
91+
We welcome this development, as it leads to shorter, more purposeful file and class names.
92+
93+
A practical example: For routed components, we prefer the suffix `page`, such as `checkout-page.ts` (class name `CheckoutPage`). It clearly indicates its purpose without referring to technical details like `Component`.
94+
A component that only displays content and contains no logic could be named `CheckoutView`, for example.
95+
96+
If you want to keep the previous behavior, you can still specify a `type` when generating, which will result in a suffix.
97+
This setting can also be made permanent in the `angular.json` file.
98+
99+
```bash
100+
ng generate component book-card --type=component
101+
```
102+
103+
104+
## Zoneless Developer Preview
105+
106+
The Angular team has been working for several years to optimize *synchronization* (also known as *change detection*) in the framework.
107+
One milestone was the introduction of signals, which allow precise change detection.
108+
In the future, Angular will no longer need the *zone.js* library to patch browser interfaces and trigger change detection.
109+
110+
<!-- We already covered change detection and the setting for a “zoneless application” in detail in our [blog post for Angular 18 (German language)](/blog/2024-06-angular18). -->
111+
112+
With Angular 20, *zoneless* is released in *Developer Preview* status.
113+
The interface is largely stable. However, short-term changes may still occur, so usage in production should be carefully considered.
114+
115+
To activate zoneless change detection, use the `provideZonelessChangeDetection()` function.
116+
The word `experimental` has been removed from the function name.
117+
It's also recommended to enable a global error handler that catches unhandled exceptions.
118+
119+
```ts
120+
// app.config.ts
121+
export const appConfig: ApplicationConfig = {
122+
providers: [
123+
provideZonelessChangeDetection(),
124+
provideBrowserGlobalErrorListeners()
125+
]
126+
};
127+
```
128+
129+
The Angular CLI offers to generate a *zoneless* application when creating a new project:
130+
131+
```bash
132+
~ ng new my-app
133+
✔ Do you want to create a 'zoneless' application without zone.js (Developer Preview)? Yes
134+
```
135+
136+
The setting can also be controlled with the new `zoneless` parameter, which can be negated using `no`:
137+
138+
```bash
139+
ng new my-app --zoneless
140+
ng new my-app --no-zoneless
141+
```
142+
143+
144+
## Structural directives `ngIf`, `ngFor`, `ngSwitch`
145+
146+
With Angular 20, the old directives `ngIf`, `ngFor`, and `ngSwitch` are marked as *deprecated*.
147+
They will likely be completely removed from the framework with Angular 22 (in one year).
148+
149+
The background is the new built-in control flow introduced with Angular 17.
150+
These directives can be replaced by Angular's built-in expressions: `@if`, `@for`, `@switch`, and `@let`.
151+
152+
```html
153+
<!-- with directive (deprecated) -->
154+
<div *ngIf="condition">Hello world</div>
155+
156+
<!-- with control flow -->
157+
@if (condition) {<div>Hello world</div>}
158+
```
159+
160+
<!-- We covered the control flow syntax in detail in our [blog post on Angular 17](/blog/2023-11-angular17#neuer-control-flow-if-for-switch). -->
161+
The Angular CLI also provides a migration script, so switching to the new syntax shouldn't be difficult:
162+
163+
```bash
164+
ng generate @angular/core:control-flow
165+
```
166+
167+
168+
## Experimental test builder for Vitest
169+
170+
The test runner Karma, still the default for unit and integration tests in Angular, is no longer being developed.
171+
Since this decision, the Angular team has been working on integrating alternative test runners into the Angular CLI.
172+
Two years ago, experimental builders for [Jest and Web Test Runner](https://blog.angular.dev/moving-angular-cli-to-jest-and-web-test-runner-ef85ef69ceca) were released.
173+
With Angular 20, another experimental integration is added for [Vitest](https://vitest.dev):
174+
Vitest has already become a staple in other web frameworks based on the [Vite](https://vite.dev) bundler.
175+
Angular's build process has already [used ESBuild with Vite since version 16](/blog/2023-05-angular16#esbuild).
176+
With this gradual switch, we can now also use Vitest for unit and integration tests.
177+
178+
Which of the experimental test runners will become Angular's new standard is not yet decided!
179+
All approaches are experimental and will be evaluated further in the coming months.
180+
181+
To use Vitest with the Angular CLI, first add the required dependencies:
182+
183+
```sh
184+
npm i vitest jsdom --save-dev
185+
```
186+
187+
Then, adjust the testing configuration in the `angular.json` file:
188+
189+
```json
190+
"test": {
191+
"builder": "@angular/build:unit-test",
192+
"options": {
193+
"tsConfig": "tsconfig.spec.json",
194+
"buildTarget": "::development",
195+
"runner": "vitest"
196+
}
197+
}
198+
```
199+
200+
In your tests, use Vitest's functions by importing the following:
201+
202+
```ts
203+
import { describe, beforeEach, it, expect } from 'vitest';
204+
// ...
205+
```
206+
207+
Run the tests as usual using `ng test`.
208+
209+
Vitest is largely compatible with the APIs of [Jest](https://jestjs.io/) and Karma, so switching is definitely worth trying.
210+
Ideally, you'll need only minimal changes in your tests.
211+
212+
One of the three experimental builders (Jest, Web Test Runner, Vitest) will likely become the new standard.
213+
We welcome the move to rely on established standards outside the Angular ecosystem and to deprecate the custom Karma test runner.
214+
We'll continue to keep you updated.
215+
216+
217+
## Stable Signal APIs: `effect`, `linkedSignal`, and `toSignal`
218+
219+
Since Angular 16, signals have paved the way for a new, reactive Angular.
220+
In Angular 20, more APIs from the signals ecosystem have now been officially released as stable: `effect`, `linkedSignal`, and `toSignal`.
221+
222+
These functions were previously experimental and are now part of the stable API set:
223+
224+
* `effect()` automatically reacts to signal changes and performs defined side effects - without lifecycle hooks.
225+
* `linkedSignal()` enables bidirectional binding between a signal and an external source - e.g. a component or a FormControl.
226+
* `toSignal()` converts observable data into a readable signal - ideal for integrating existing streams.
227+
228+
You'll find more details and examples in our Signals series:
229+
230+
* [Angular 19: Introducing LinkedSignal for Responsive Local State Management](https://angular.schule/blog/2024-11-linked-signal)
231+
* [Angular 19: Mastering effect and afterRenderEffect](https://angular.schule/blog/2024-11-effect-afterrendereffect)
232+
233+
234+
## httpResource: Load data with signals
235+
236+
In October 2024, the new experimental Resource API was introduced. We covered it in detail in a [blog post](https://angular.schule/blog/2025-05-resource-api).
237+
It connects the synchronous world of signals with asynchronously fetched data, e.g. via HTTP.
238+
The data is loaded asynchronously using a loader and provided via signals.
239+
240+
A few weeks ago, another variant of the Resource was introduced: `httpResource`.
241+
It uses Angular's `HttpClient` under the hood to perform an HTTP request directly.
242+
You no longer need to write the request yourself - the resource handles it for you.
243+
244+
```ts
245+
booksResource = httpResource<Book[]>(
246+
() => 'https://api.example.org/books',
247+
{ defaultValue: [] }
248+
);
249+
// ...
250+
console.log(booksResource.value())
251+
```
252+
253+
The request must be generated using a function.
254+
This is because it runs in a *reactive context*: If you use signals inside the function, the request is re-executed automatically when any of those signals change.
255+
Additional request details can be passed in an options object:
256+
257+
```ts
258+
booksResource = httpResource<Book[]>(
259+
() => ({
260+
url: 'https://api.example.org/books',
261+
params: {
262+
search: 'Angular'
263+
}
264+
})
265+
);
266+
```
267+
268+
Please note that a resource is only meant for *retrieving* data from an API and exposing it with signals.
269+
Write operations such as create, update, or delete cannot be handled with a resource.
270+
You must continue to use `HttpClient` directly for those.
271+
272+
273+
## Miscellaneous
274+
275+
You can always find all details about the updates in the changelogs for [Angular](https://github.com/angular/angular/blob/main/CHANGELOG.md) and the [Angular CLI](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md).
276+
We've compiled a few interesting highlights here:
277+
278+
- **`provideServerRouting()` deprecated:** The function `provideServerRouting()` is deprecated. Instead, use `provideServerRendering()` with the `withRoutes()` feature. (see [commit](https://github.com/angular/angular-cli/commit/33b9de3eb1fa596a4d5a975d05275739f2f7b8ae))
279+
- **Chrome DevTools:** Integration of Angular into Chrome DevTools has significantly improved. The *Performance* tab now lets you analyze Angular's change detection and other performance parameters.
280+
- **Official mascot:** The Angular team wants to introduce an official mascot for the framework - and the community is invited to participate! Vote for your favorite or share your thoughts in the [RFC on GitHub](https://github.com/angular/angular/discussions/61733).
281+
282+
<hr>
283+
284+
285+
We wish you lots of fun developing with Angular 20!
286+
Do you have questions about the new version or about our book? Reach out to us!
287+
288+
**Best wishes from
289+
Ferdinand, Danny, and Johannes**
290+
291+
<hr>
292+
293+
<small>**Cover photo:** Morning mood at Anklamer Stadtbruch wetland. Photo by Ferdinand Malcher</small>
245 KB
Loading

0 commit comments

Comments
 (0)