Recommended Free Tools
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To create a custom pipe in Angular, write a TypeScript class decorated with @Pipe, give it a name, implement a transform method, and make the class available to the template that uses it. In a standalone component you add the pipe to the component’s imports array. In an NgModule-based project you list it in the module’s declarations. The name you set in @Pipe is what follows the | character in a template expression.
The shape of a custom pipe
Every custom pipe has the same four parts. Once you can name them, the rest of the process is repetition.
- A decorated class. The
@Pipedecorator from@angular/coremarks the class as a pipe and holds its metadata. - A pipe name. The
nameproperty is the identifier used after|in a template, such as{{ word | reverse }}. - A
transformmethod. This method contains the transformation. Angular calls it with the bound value as the first argument. - Registration in the consuming context. The template’s component must be able to see the pipe, either through its standalone
importsor through an NgModule’sdeclarations.
The class is expected to implement the PipeTransform interface, which defines the shape of transform. Angular’s PipeTransform API reference describes the signature as transform(value, ...args): the bound value comes first, and any optional parameters follow it.
How do I create a custom pipe in Angular?
The steps below build a pipe called reverse that flips a string. The Angular tutorial’s create a pipe lesson uses a similar exercise and a class named StarPipe; the names here are only examples.
#1 Best Overall
- Generate or create the file. Create
reverse.pipe.tsin the folder of the component that will use it. If you use the Angular CLI,ng generate pipe reversecreates a file and class with the same structure. - Import the decorator and the interface. Add
import { Pipe, PipeTransform } from '@angular/core';at the top of the file. - Declare the class with a name. Use
@Pipe({ name: 'reverse' }). Pick a lowerCamelCase name that describes the task, because it is what appears in templates. - Write
transformwith explicit types. Keep the input and output types clear so the template and the code agree about what goes in and what comes out. - Register the pipe in the consuming component or module, as described in the next section.
- Use it in the template with
{{ word | reverse }}.
import { Pipe, PipeTransform } from '@angular/core';
import { reverseText } from './text-utils';
@Pipe({
name: 'reverse',
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return reverseText(value);
}
}
The pipe delegates the actual work to reverseText, which is defined in a separate file. That separation is covered in the section on reusing the logic outside templates.
How do I use a custom pipe in a component?
How you make a pipe available depends on how the project is organized. Angular’s current documentation supports standalone pipes imported by components, and it also documents NgModule declarations for module-based code. Both are valid, but they are not interchangeable in the same place.
| Project setup | Where the pipe is registered | What the consuming code looks like |
|---|---|---|
| Standalone components | The imports array of each component whose template uses the pipe |
imports: [ReversePipe] in the component’s @Component metadata |
| NgModule-based | The declarations array of the NgModule that declares the consuming component |
declarations: [ReversePipe, GreetingComponent] in the module |
Standalone component example
Import the pipe class into the component that uses it. The template can then reference the pipe by name.
Rank #2
import { Component } from '@angular/core';
import { ReversePipe } from './reverse.pipe';
@Component({
selector: 'app-greeting',
imports: [ReversePipe],
template: '<p>{{ word | reverse }}</p>',
})
export class GreetingComponent {
word = 'Angular';
}
Pipes are not injected into a component in the way services are. The component’s imports array tells Angular which pipes its template may use.
NgModule-based example
In a module-based project, the pipe is listed in the declarations of the NgModule that declares the component using it. A standalone pipe is imported rather than listed in declarations, so keep the two approaches separate within a single project.
import { NgModule } from '@angular/core';
import { ReversePipe } from './reverse.pipe';
import { GreetingComponent } from './greeting.component';
@NgModule({
declarations: [ReversePipe, GreetingComponent],
})
export class GreetingModule {}
If Angular reports that it cannot find a pipe in a template, check first that the pipe is listed in the consuming component’s imports or in the declarations of the module that declares that component. A pipe that exists in a file but is not registered in the right place produces this symptom.
Rank #3
How do I pass arguments to an Angular pipe?
Pipe parameters are added after the pipe name, separated by colons. Angular passes the value on the left of | as the first argument to transform, then each colon-separated value in order. The method parameters must line up with that order.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'truncate',
})
export class TruncatePipe implements PipeTransform {
transform(value: string, limit = 10, ellipsis = '…'): string {
return value.length > limit ? value.slice(0, limit) + ellipsis : value;
}
}
<p>{{ title | truncate:20:'...' }}</p>
<p>{{ title | truncate }}</p>
| Template expression | Value passed to value |
limit |
ellipsis |
|---|---|---|---|
title | truncate:20:'...' |
The value of title |
20 (from the first colon argument) | '...' (from the second colon argument) |
title | truncate |
The value of title |
10 (default) | '…' (default) |
Give defaults to optional parameters, as shown, so that the pipe still works when a template omits them. Arguments are positional: you cannot skip the first one and pass only the second without writing a value for it.
Purity and change detection
Pipes are pure by default. A pure pipe runs its transform method only when its primitive input changes or when an object reference changes. Angular does not look inside arrays or objects to detect in-place edits. That is why a pure pipe that receives an array will not update when code pushes a new item into the same array.
Rank #4
// Not detected by a pure pipe: the array reference stays the same
this.items.push(newItem);
// Detected: a new array reference is created
this.items = [...this.items, newItem];
The better fix is almost always to update data immutably, by creating a new array or object whenever the data changes. Making the pipe impure is the other option, and the Angular guide treats it with caution. Angular’s pipes guide includes this warning:
“IMPORTANT: Avoid creating impure pipes unless absolutely necessary, as they can incur a significant performance penalty if used without care.”
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchAn impure pipe is declared with pure: false in the @Pipe metadata:
@Pipe({
name: 'latest',
pure: false,
})
export class LatestPipe implements PipeTransform {
// runs on every change-detection cycle
}
The guide describes the penalty as qualitative, not as a measured number. An impure pipe runs on every change-detection cycle, so its cost grows with how often Angular checks the view and how expensive the transformation is. Use it only when internal state or in-place mutation genuinely has to be observed, and prefer immutable updates before reaching for it.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Reusing the transformation outside templates
Angular describes pipes as template operators rather than injectable services. A pipe class is designed to be used in templates, so the cleanest way to share its logic is to move the transformation into a standalone function. The pipe then calls that function, and any service or other code can import it directly.
// text-utils.ts
export function reverseText(value: string): string {
return [...value].reverse().join('');
}
Angular’s guide puts the principle directly: “When you create a custom pipe, extract the transformation into a standalone function.” The same guide also notes that built-in formatting pipes have function equivalents in @angular/common. Functions such as formatDate, formatCurrency, formatNumber, and formatPercent can be called from code instead of injecting the matching pipe class.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →The function approach keeps the template and non-template code consistent. If the rule changes, you update one function.
Quick Recap
Checklist before you ship a custom pipe
- The class is decorated with
@Pipeand has a uniquename. - The class implements
PipeTransformandtransformhas typed input and output. - The pipe is imported into the standalone component’s
imports, or declared in the correct NgModule. - Optional parameters have defaults and match the order used in the template.
- The pipe is pure unless you have confirmed that the data cannot be updated immutably.
- Logic that other code needs is in a standalone function, not only inside the pipe class.
“
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

