Angular 16+ Signals vs Decorators
Angular 16 introduced a new Composition API built around signals—a reactive primitive designed to make reactivity in Angular more powerful, predictable, and ergonomic. Along with this, Angular provided new functions: signal(), input(), and output() that offer a modern alternative to the classic @Input() and @Output() decorators.
In this article, we’ll explore:
- What are
signal(),input(), andoutput()? - How do they compare with
@Input()and@Output()? - When should you use which?
1. The New Composition API
import { signal, input, output } from '@angular/core';
These are functions, not decorators. They allow defining state and bindings in a more reactive and composable way.
Example:
@Component({
selector: 'user-card',
standalone: true,
template: `<p>{{ name() }}</p>`
})
export class UserCardComponent {
name = input.required<string>();
onClick = output<MouseEvent>();
}
Benefits:
- Strongly typed with required/optional inputs
- Fully signal-compatible
- Perfect for standalone and modern components
2. The Classic Decorator API
import { Input, Output, EventEmitter } from '@angular/core';
These are decorators used since Angular 2 for parent-child communication.
Example:
@Component({
selector: 'user-card',
standalone: true,
template: `<p>{{ name }}</p>`
})
export class UserCardComponent {
@Input() name!: string;
@Output() onClick = new EventEmitter<MouseEvent>();
}
Benefits:
- Works with all Angular versions
- Compatible with modules and older codebases
Side-by-Side Comparison
| Feature |
@Input() / @Output()
|
input() / output()
|
|---|---|---|
| API Type | Decorator | Function |
| Introduced In | Angular 2 | Angular 16 |
| Reactive? | No | Yes (signals) |
| Required Inputs | Manual ! or guards |
input.required<T>() |
| Works with Signals | Manual wrapping needed | Native |
| Event System | EventEmitter | Reactive callback via signals |
| Recommended for | Legacy apps, decorator style | Modern apps with signals |
When to Use Each?
| Use Case | Recommended API |
|---|---|
| You’re using signals |
input() / output()
|
| You’re building modern apps |
input() / output()
|
| You’re working with legacy code |
@Input() / @Output()
|
Using EventEmitter patterns |
@Output() |
Summary
Angular’s evolution to signals is a major step forward in ergonomics and reactivity. If you’re starting a new Angular project or refactoring components to use the new standalone style, we highly recommend adopting input(), output(), and signal().
However, decorators like @Input() and @Output() remain powerful and necessary when working with older or module-based codebases.
Both APIs can coexist, giving you the flexibility to migrate progressively.

Top comments (1)
Wow, Angular keeps changing things up - I feel like I'm always playing catch up. I kinda like the feel of these signals though, feels like less fighting with the old stuff.