What's new in Angular 18
In this new version of the framework, numerous features have been incorporated that significantly improve the DX. All of this feature will be released in the official v18 and in minors.
1. TypeScript 5.4 and Node.js v22
TypeScript 5.4 brings the following new features:
Smartes control-flow analysis in closures
The
NoInferutility typeBroader support for bundlers and runtimes
Quick fixes for missing parameters
Improved auto-imports
Node.js 22 include:
WebSocket Client
Experimental ESM Support
Node
—watchmodeIncreased Default Highwater Marks for Streams
2. New command ng dev
This new command is an alias for the ng serve command. The Angular team has decided to add this command to be aligned with other frameworks that also use it in this way.
3. New build system @angular/build
This new package contains a small subset of the @angular-devkit/build-angular.
This new package does not require Webpack under the hood. It works with ESBuild and vite.
By default, in our angular.json we will see a migration to the new build system.
One drawback is that if you're using Karma and Jasmine, you're going to need Webpack. Therefore, you will need the other package. However, Angular is smart enough to know that when you run your tests it has to use one builder or another. This way, although in your angular.json you have @angular/build as a builder and you are using Karma and Jasmine, below it will use the builder through Webpack.
4. New assets directory
Our assets folder was used to keep static files such as images, translations, fonts, etc. In Angular 18 this folder will be renamed to public. So when we create a new v18 app we will receive a public folder instead of assets.
5. Deferrable views become stable
This is very good news since it significantly improves the initial bundle. I have a video on my YouTube channel explaining everything about deferrable views that I consider very interesting for you to watch.
In this video you can find:
Dynamic Imports
Deferrable views uses
Ways to control deferrable views
@placeholder, @loading, @error
predefined triggers (with on: idle, viewport, interaction...) and custom (when) / prefetch
@defer and SSR, lazy-loading
6. Updates on resolvers and guards
parseUrl(): parses a string into aUrlTreeWe can use this approach when for example we want to perform a redirect on a guard. We could use a
navigate()but this would rather return a Promise<boolean> instead of aUrlTree. Keep in mind that you can only use theNavigationExtrasinsidenavigate(), not inparseUrl().New
RedirectCommand APIAllow us to use the NavigationExtras inside the resolvers and guards and we can import it from
@angular/router.In this case, instead of returning a
UrlTreeit returns an instance of aRedirectCommand. So, in his constructor we pass theUrlTreeand theNavigationExtrasparams.So we can replace the above code with:
7. Updates on route configuration
The second route return a redirectTo products in case we go to the root. Angular allows us now to also use this redirectTo with a function.
As you can see we can pass an arrow function with a route parameter:
As the documentation says we can also inject dependencies inside function and use them as we want. And the param that we pass in the function is of type ActivatedRouteSnapshot:
8. Content projection - Default fallback content
We can have a default content for the ng-content in Angular 18.
Before this, all the content that we put into the component itself would go there on that ng-content. Now, if we do not especify nothing, we will have the default content:
Guess the results:
For more, read the artible by Davide Passafaro.
9. Unified Control State Change Events (Forms)
Our FormContrl (AbstractControl) has a new property called events which we can subscribe to listen to the following events:
PristineEvent: Indicates whether the control has been interacted with (pristineproperty).StatusEvent: Provides the current status of the form control (statusproperty).TouchedEvent: Signals whether the control has been touched (touchedproperty).ValueChangeEvent: Delivers the updated value of the control (valueproperty)
We can now have a more fine-grained control over our form controls.
For more, read Netanel Basal post.
We also have FormSubmittedEvent which is fired when the form is submitted and FormResetEvent which is fired when a form is reset.
10. Zoneless Change Detection + Hybrid Approach
We can use this function provideExperimentalZonelessChangeDetection() to not use the state/state changes of ZoneJS to schedule change detection in the application.
And therefore we must trigger change detection manually with markForCheck().
Also if we use ngZone.runOutsideAngular() we can tell with our provideZoneChangeDetection() function to ignore changes inside runOutsideAngular() with ignoreChangesOutsideZone property and accomplish with this what is called as Hybrid Change Detection.
On the other hand, imagine you have two events:
Both event handlers will be called and we will have 2 change detections triggered. We can coalesce (merge) such kind of events to only trigger change detection only once with:
If you want to learn more I have a video with all of this stuff explained in depth:
Finally, if you want to go zoneless with your current project, Angular provides you a functionality to check if you can go zoneless or not. You can use provideExperimentalCheckNoChangesForDebug().
This will run a change detection every second and check if any component has been changed without triggering a change detection. If such a change is detected, a NG0100: ExpressionChangedAfterItHasBeenCheckedError error will be thrown in the console. This should allow you to track down the components that need to be updated to work with zoneless change detection.
11. @let syntax
We can now have in our templates local variables. So until today we came with this approach:
With new syntax:
You can read more in this amazing post by Enea Jahollari.
12. Angular.io redirects to angular.dev
13. Built-in control flow is now stable
You must switch to the new control flow in order to boost performance!
14. Material 3 is now stable
Customize componentes should be easy now with the evolution to the Material Design based on design tokens.
15. More changes
withNavigationErrorHandler()
Replay events on clientHydratation with EventDispatch
Deprecated HttpClientModule()
withHttpTransferCacheOption ()
HOST_TAG_NAME token
ExperimentalPendingTasks API
Deprecate async() in favor of waitForAsync()
If you want a detailed and in depth description of each, you can check mi video:
Thanks for reading so far 🙏
I’d like to have your feedback so please leave a comment, clap or follow. 👏
Then, if you really liked it share it among your community, tech bros and whoever you want. And don’t forget to follow me on LinkedIn, on Medium or YouTube. 👋😁





















