This content originally appeared on Level Up Coding - Medium and was authored by Vitalii Shevchuk

Angular is going through a big makeover. The web framework made by Google and using TypeScript is getting ready for version 16, which will have many new and exciting things. For example, it will make it easier to use server-side rendering, which means faster and smoother web pages. It will also have better runtime performance, which means fewer bugs and crashes.
Version 16 is not out yet, but you can try the first release candidate version now. It has more changes than any previous major version (except for the jump from Angular to Angular 2). Angular is becoming more modern and powerful, and version 16 is just the start. Here are some of the cool things you can expect in this release.
Content
- Signals: A New Way of Managing State Changes
- Server-Side Rendering: Faster and Smoother
- Developer Experience: Better and Easier
- Required component inputs
- Dependency injection debugging APIs
- Improved documentation and schematics for standalone components
- Exploring options to improve JavaScript bundles created by Angular CLI
- Other Features and Improvements
- Support for Tailwind CSS
- Support for CSS isolation
- Support for native Trusted Types
- Conclusion
- Learn More
Signals: A New Way of Managing State Changes
One of the most exciting features of Angular 16 is the introduction of signals, a new way of managing state changes in Angular applications. Signals are inspired by Solid.js, a reactive UI library that uses a push/pull pattern to create reactive value graphs.
Signals are functions that return a value (get) and can be updated by calling them with a new value (set). Signals can also depend on other signals, creating a reactive value graph that automatically updates when any dependencies change. Signals can be used with RxJS observables, which are still supported in Angular 16, to create powerful and declarative data flows.
Signals offer several advantages over the traditional change detection mechanism in Angular, which relies on Zone.js to monkey-patch browser APIs and trigger change detection globally. Signals allow you to run change detection only in affected components, without traversing the entire component tree or using Zone.js. This improves runtime performance and reduces complexity.
Signals also make your code more expressive and easier to reason about, as you can clearly see the dependencies and updates of your values. Signals also enable fine-grained reactivity, which means you can control when and how your values change.
Here is a possible example of using signals in Angular 16:
// Import the createSignal function
import { createSignal } from '@angular/core';
// Create a component that uses signals
@Component({
selector: 'app-counter',
template: `
<h1>{{ count }}</h1>
<button (click)="increment()">+</button>
<button (click)="decrement()">-</button>
`
})
export class CounterComponent {
// Create a signal instance for the count value
count = createSignal(0);
// Increment the count value by calling the next method on the signal
increment() {
this.count.next(this.count.value + 1);
}
// Decrement the count value by calling the next method on the signal
decrement() {
this.count.next(this.count.value - 1);
}
}
Server-Side Rendering: Faster and Smoother
Another major improvement in Angular 16 is the support for non-destructive hydration, which makes server-side rendering (SSR) faster and smoother. SSR is a technique that renders your application on the server and sends the HTML content to the browser, where it is converted into a fully interactive and functional web page by attaching JavaScript behavior and event listeners.
SSR reduces the time-to-interactive (TTI) and improves SEO and accessibility. SSR has been available in frameworks like React or Next.js for a while, but it was not easy to implement in Angular. In Angular 16, SSR will be supported out of the box, making SSR applications faster and smoother.
Non-destructive hydration means that the browser does not overwrite or remove any existing HTML content or attributes when hydrating the application. This preserves any server-side optimizations or customizations that you may have applied to your HTML content. Non-destructive hydration also avoids potential conflicts or errors that may arise from mismatched HTML content between the server and the client.
Developer Experience: Better and Easier
Angular 16 also introduces some new features and improvements that enhance the developer experience and code quality of Angular applications. Some of these features are:
- Required component inputs: This feature allows you to mark some inputs of a component as required, meaning the parent component must provide them, or else an error will be thrown. This helps catch bugs and typos at compile time and ensures that components receive all the necessary data to function properly. Required component inputs also make components more self-documenting and easier to use.
@Component({})
class HomeComponent {
@Input({required: true}) someRequiredInput;
}
- Dependency injection debugging APIs: This feature allows you to inspect and debug the dependency injection system in Angular applications. You can use these APIs to get information about the providers, tokens, injectors, scopes, and instances of your dependencies. You can also use these APIs to simulate different scenarios or test cases for your dependencies.
Here is a possible example of using dependency injection debugging APIs in Angular 16:
// Import the DebugInjector interface
import { DebugInjector } from '@angular/core';
// Inject the DebugInjector service in the constructor
constructor(private debugInjector: DebugInjector) {}
// Use the DebugInjector service to get information about the dependencies
ngOnInit() {
// Get the provider for a token
const provider = this.debugInjector.getProvider(MyService);
// Get the injector for a token
const injector = this.debugInjector.getInjector(MyService);
// Get the scope for a token
const scope = this.debugInjector.getScope(MyService);
// Get the instance for a token
const instance = this.debugInjector.getInstance(MyService);
// Simulate a different scenario for a token
this.debugInjector.simulate(MyService, {
// Provide a different value for the token
value: new MyService('test'),
// Override the scope for the token
scope: 'root',
// Override the injector for the token
injector: this.debugInjector.createInjector([MyService])
});
// Reset the simulation for a token
this.debugInjector.reset(MyService);
}
In this example, we create a simple component that uses dependency injection debugging APIs to get and manipulate information about its dependencies. We import the DebugInjector interface from @angular/core and inject it as a service in the constructor. We then use various methods on the DebugInjector service to access and modify the provider, injector, scope, and instance of a dependency token. We can also use the simulate and reset methods to create different scenarios or test cases for our dependencies. This way, we can debug and troubleshoot our dependency injection system more easily and effectively.
- Improved documentation and schematics for standalone components: This feature improves the documentation and schematics for creating standalone components in Angular applications. Standalone components are components that do not belong to any module and can be used anywhere in your application. Standalone components are useful for creating reusable UI elements or libraries.
- Exploring options to improve JavaScript bundles created by Angular CLI: This feature explores different options to optimize the JavaScript bundles created by Angular CLI, such as using ES modules, tree-shaking, code-splitting, or differential loading. These options aim to reduce the bundle size and improve the loading performance of Angular applications.
Other Features and Improvements
Angular 16 also adds some other features and improvements that enhance the functionality and usability of the framework. Some of these features are:
- Support for Tailwind CSS: Tailwind CSS is a popular utility-first CSS framework that lets you style your components with classes instead of writing custom CSS. Tailwind CSS offers many benefits such as faster development, consistent design, responsive design, customization, and extensibility. Angular 16 supports Tailwind CSS out of the box, making it easy to use in your Angular projects.
- Support for CSS isolation: CSS isolation is a feature that allows you to scope your component styles to prevent them from leaking or conflicting with other styles. CSS isolation can be achieved by using shadow DOM or emulated encapsulation. Angular 16 supports both options and lets you choose the one that suits your needs.
Here is a possible example of using CSS isolation in Angular 16:
// Import the ViewEncapsulation enum
import { Component, ViewEncapsulation } from '@angular/core';
// Create a component that uses shadow DOM for CSS isolation
@Component({
selector: 'app-shadow',
template: `
<h1>Shadow DOM</h1>
<p>This component uses shadow DOM for CSS isolation.</p>
`,
styles: [`
h1 {
color: blue;
}
`],
// Set the encapsulation property to ViewEncapsulation.ShadowDom
encapsulation: ViewEncapsulation.ShadowDom
})
export class ShadowComponent {}
// Create a component that uses emulated encapsulation for CSS isolation
@Component({
selector: 'app-emulated',
template: `
<h1>Emulated Encapsulation</h1>
<p>This component uses emulated encapsulation for CSS isolation.</p>
`,
styles: [`
h1 {
color: red;
}
`],
// Set the encapsulation property to ViewEncapsulation.Emulated (default value)
encapsulation: ViewEncapsulation.Emulated
})
export class EmulatedComponent {}
The first component uses shadow DOM, which is a native browser feature that creates a separate DOM tree and style scope for the component. The second component uses emulated encapsulation, which is an Angular feature that adds unique attributes to the component’s elements and styles to simulate the behavior of shadow DOM
- Support for native Trusted Types: Trusted Types are a browser feature that helps prevent cross-site scripting (XSS) attacks by enforcing strict rules on how strings are used in sensitive contexts. Trusted Types can prevent malicious code from being executed by sanitizing or rejecting unsafe strings. Angular 16 supports native Trusted Types and automatically applies them to your templates and expressions.
Here is a possible example of using Trusted Types in Angular 16:
// Import the createTrustedHTML function
import { createTrustedHTML } from '@angular/core';
// Create a component that uses Trusted Types
@Component({
selector: 'app-hello',
template: `
<div [innerHTML]="message"></div>
`
})
export class HelloComponent {
// Create a trusted HTML value using the createTrustedHTML function
message = createTrustedHTML('<h1>Hello, world!</h1>');
// Alternatively, use the safevalues library to create trusted values
// import { createHtml } from 'safevalues/implementation/html_impl';
// message = createHtml('<h1>Hello, world!</h1>');
}
- Support for dynamic imports of router data: This feature is a new way of getting router information in your component without injecting the ActivatedRoute service. With this feature, you can bind some router data to your component inputs, such as the route params, data, query params, fragment, and url. This can make your code simpler and cleaner.
For example, instead of writing this:
// Import the ActivatedRoute service
import { ActivatedRoute } from '@angular/router';
// Inject the ActivatedRoute service in the constructor
constructor(private route: ActivatedRoute) {}
// Use the ActivatedRoute service to get the router data
ngOnInit() {
// Get the route params
this.route.params.subscribe(params => {
// Do something with params
});
// Get the route data
this.route.data.subscribe(data => {
// Do something with data
});
// Get the query params
this.route.queryParams.subscribe(queryParams => {
// Do something with queryParams
});
// Get the fragment
this.route.fragment.subscribe(fragment => {
// Do something with fragment
});
// Get the url
this.route.url.subscribe(url => {
// Do something with url
});
}
You can write this:
// Define the component inputs for the router data
@Input() params: Params;
@Input() data: Data;
@Input() queryParams: Params;
@Input() fragment: string;
@Input() url: UrlSegment[];
// Use the component inputs to get the router data
ngOnInit() {
// Do something with params
// Do something with data
// Do something with queryParams
// Do something with fragment
// Do something with url
}
To use this feature, you need to enable it in the RouterModule by setting the bindToComponentInputs option to true. For example:
// Import the RouterModule and Routes
import { RouterModule, Routes } from '@angular/router';
// Define the routes for the application
const routes: Routes = [
// Use dynamic imports to load modules lazily
{
path: 'home',
loadChildren: () => import('./home/home.module').then(m => m.HomeModule)
},
{
path: 'about',
loadChildren: () => import('./about/about.module').then(m => m.AboutModule)
},
{
path: 'contact',
loadChildren: () => import('./contact/contact.module').then(m => m.ContactModule)
}
];
// Import the modules for the application
@NgModule({
imports: [
// Use the RouterModule.forRoot method to register the routes and enable bindToComponentInputs option
RouterModule.forRoot(routes, { bindToComponentInputs: true })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
- A new date range picker component in Angular Material: Angular Material is a UI component library that implements the Material Design guidelines. Angular Material provides many components that can be used to create beautiful and functional user interfaces. Angular 16 adds a new date range picker component to Angular Material, which allows you to select a start and end date from a calendar.
Conclusion
Angular 16 is a huge update that brings many improvements and new features to the framework. Angular 16 is set to revolutionize state management with signals. With improved developer experience and the natural hydration of server-side rendering applications, developers will have greater flexibility to create engaging user interfaces.
Other features cited by Google for Angular 16 include revisiting Angular’s reactivity model and making Zone.js optional to improve runtime performance, the introduction of dependency injection debugging APIs, improving documentation and schematics for standalone components, exploring options to improve JavaScript bundles created by Angular CLI, and document refactoring.
Learn More
- 🌳 Best Practices of React Composite Pattern for Hierarchical Components
- 🤝 Improve State Management in React With Mediator Design Pattern
- 🗣️ Best Practice of React Interpreter Pattern: Writing Cleaner and More Readable Code
- 🔗 Best Practices of Chain of Responsibility Pattern in React
More content at PlainEnglish.io.
Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.
🅰️ New Angular 16 is Going Big in 2023: Everything You Need to Know was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Vitalii Shevchuk

Vitalii Shevchuk | Sciencx (2023-05-04T21:42:16+00:00) ️ New Angular 16 is Going Big in 2023: Everything You Need to Know. Retrieved from https://www.scien.cx/2023/05/04/%ef%b8%8f-new-angular-16-is-going-big-in-2023-everything-you-need-to-know/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.