✅ Angular Best Practices (2025 Edition)

If you’re building Angular apps in 2025, here are some practical, performance-oriented patterns you should definitely be using — from Signals and Change Detection to Storybook integration and template composition with ng-content.


⚡ Signals for Reactive State Management

Signals are the go-to reactive primitive in Angular for change detection and improved performance.

Declaring a Signal

readonly totalSearchRelevantBrandCount = signal<number>(0);

Updating a Signal

Use .set() to assign a new value:

this.totalSearchRelevantBrandCount.set(totalRelevantBrandCount);

Using a Signal in the Template

<h1>Total Brands: {{ totalSearchRelevantBrandCount() }}</h1>

🔄 Managing Observable Subscriptions

To avoid memory leaks, manage all subscriptions in one place using a Subscription instance:

private readonly subs = new Subscription();

this.subs.add(
this.route.queryParamMap.subscribe(queryParams => {
this.isModal = !!queryParams.get('isModal');
})
);

this.subs.add(
this.route.paramMap.subscribe(params => {
console.log("Second subscription triggered");
})
);

Clean Up in ngOnDestroy

ngOnDestroy(): void {
this.subs.unsubscribe();
}

🧩 Using ng-content for Template Composition

In your child component (app-panel-item), use ng-content to allow flexible content projection:

<div class="column-2">
<ng-content select="h5" />
<ng-content select="h6" />
<ng-content select="small" />
<ng-content select=".action-text" />
</div>

Parent Component Example

<app-panel-item><h4>Proposal History</h4></app-panel-item>
<app-panel-item><h4>Cover Page</h4></app-panel-item>
<app-panel-item><h4>About Us</h4></app-panel-item>

🧠 Change Detection: Always Use OnPush

For better performance, set your components to use ChangeDetectionStrategy.OnPush.

@Component({
selector: 'app-panel-item',
templateUrl: './panel-item.component.html',
styleUrls: ['./panel-item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})

This ensures Angular only checks for changes when inputs change or a signal updates — not on every event.


📚 Component Isolation with Storybook

Storybook is a great tool to build, test, and visually isolate components.

Setup Example for PanelItemComponent

const meta: Meta<PanelItemComponent> = {
title: 'Shared Components/Panel Item',
component: PanelItemComponent,
decorators: [
moduleMetadata({
imports: [],
providers: [],
declarations: [PanelGroupComponent, SubtleLabelComponent],
}),
],
};

export default meta;
type Story = StoryFn<PanelItemComponent>;

Usage Story

export const Default: Story = () => ({
template: `
<app-panel-group>
<app-panel-item><h4>Living Room</h4><h5>$123</h5><h6>$234</h6></app-panel-item>
<app-panel-item><h4>Basement</h4><h6>$123</h6><small>2 items</small></app-panel-item>
</app-panel-group>

<app-panel-group>
<app-panel-item><h4>Proposal Total</h4><h5>$234</h5></app-panel-item>
</app-panel-group>

<app-panel-group class="gray">
<app-panel-item><h4>Proposal Total</h4><h5>$234</h5></app-panel-item>
</app-panel-group>
`,
});

Final Thoughts

In 2025, Angular is all about performance and maintainability. With signals, OnPush strategy, clean subscription management, and smart use of ng-content, you’re setting your app up for long-term success. Tools like Storybook only make the process of building robust, testable components even easier.

Let me know if you want a checklist version or a real-world sample project based on these practices!

Leave a Comment

Your email address will not be published. Required fields are marked *