Angular Pipe Created: 11 Jan 2026 Updated: 11 Jan 2026

Custom Pipe

In Angular, Pipes are powerful tools used to transform data directly within your HTML templates.1 While Angular provides many built-in pipes (like DatePipe, UpperCasePipe, and CurrencyPipe), there are often scenarios where you need specialized formatting logic unique to your application. This is where Custom Pipes come in.

Why Use Custom Pipes?

  1. Reusability: Write the logic once and use it across any component in your application.2
  2. Clean Templates: Keeps your HTML clean by moving complex transformation logic into a dedicated class.
  3. Performance: Angular optimizes pipes (especially Pure Pipes) to only re-run when the input data changes.3

Creating a Custom Pipe: Step-by-Step

To create a custom pipe, you need to implement the PipeTransform interface and use the @Pipe decorator.4

1. The Scenario

Imagine you are building a blog and want to show a "Reading Time" estimate based on the word count of an article.

2. The Implementation

Create a file named reading-time.pipe.ts:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'readingTime',
standalone: true // Making it standalone for modern Angular apps
})
export class ReadingTimePipe implements PipeTransform {

/**
* @param value The text content to analyze
* @param wordsPerMinute Average reading speed (defaulting to 200)
* @returns A formatted string indicating minutes
*/
transform(value: string, wordsPerMinute: number = 200): string {
if (!value) return '0 min read';

const wordCount = value.trim().split(/\s+/).length;
const minutes = Math.ceil(wordCount / wordsPerMinute);

return `${minutes} min read`;
}
}

Using the Pipe in a Component

Once defined, you need to import it into your component (if using standalone components) and apply it using the pipe operator (|) in your template.

Component Code:

import { Component } from '@angular/core';
import { ReadingTimePipe } from './reading-time.pipe';

@Component({
selector: 'app-article',
standalone: true,
imports: [ReadingTimePipe],
template: `
<article>
<h1>Understanding Angular Pipes</h1>
<p><i>{{ articleContent | readingTime }}</i></p>
<div class="content">{{ articleContent }}</div>
</article>
`
})
export class ArticleComponent {
articleContent = "Angular is a platform and framework for building single-page client applications...";
}

Advanced Example: A Parameterized Truncate Pipe

Sometimes you want to shorten a long string (like a product description) and allow the developer to decide exactly how many characters to show and what symbol to use at the end (e.g., ... or Read More).

1. The Implementation

Create a file named truncate.pipe.ts. Notice how the transform method accepts additional arguments after the initial value.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'truncate',
standalone: true
})
export class TruncatePipe implements PipeTransform {

/**
* @param value The string to truncate
* @param limit The number of characters to keep (default: 20)
* @param suffix The string to append at the end (default: '...')
*/
transform(value: string, limit: number = 20, suffix: string = '...'): string {
if (!value) return '';
if (value.length <= limit) return value;

return value.substring(0, limit) + suffix;
}
}

2. Using Parameters in the Template

In Angular, you pass parameters to a pipe using the colon (:) symbol. You can chain as many parameters as the transform method is designed to handle.

Component Template:

<p>{{ longDescription | truncate }}</p>

<p>{{ longDescription | truncate:50 }}</p>

<p>{{ longDescription | truncate:10:' (see more)' }}</p>

How it Works

  1. First Argument: The value before the pipe operator (longDescription) always maps to the first parameter of the transform method.
  2. Subsequent Arguments: Everything after the first colon maps to the second, third, and fourth parameters respectively.
  3. Type Safety: Because we are using TypeScript, if you try to pass a string where the pipe expects a number (like truncate:'high'), the compiler will throw an error, helping you catch bugs early.


The Angular CLI (Command Line Interface) is the most efficient way to create pipes. It automates the "boilerplate" work by generating the necessary files and, if you aren't using standalone components, automatically declaring the pipe in your AppModule.

The Command

The basic syntax for generating a pipe is:

ng generate pipe pipe-name

(Shortcut: ng g p pipe-name)

Step-by-Step Example: Creating a "File Size" Pipe

Let's say you want to create a pipe that converts a raw number of bytes into a human-readable format (like KB or MB).

1. Run the Command

Open your terminal in your project folder and run:

ng g p formatFileSize

2. What the CLI Does

The CLI will perform two main actions:

  1. Creates format-file-size.pipe.ts: A skeleton file with the @Pipe decorator and PipeTransform interface already in place.
  2. Creates format-file-size.pipe.spec.ts: A unit test file so you can immediately start testing your logic.
  3. Updates AppModule / Component: If you aren't using standalone mode, it adds the pipe to the declarations array of your module.

3. Add Your Logic

Open the newly generated format-file-size.pipe.ts and add the transformation logic:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'formatFileSize',
standalone: true
})
export class FormatFileSizePipe implements PipeTransform {

transform(bytes: number, extension: string = 'MB'): string {
if (isNaN(bytes)) return '0';

if (extension === 'KB') {
return (bytes / 1024).toFixed(2) + ' KB';
}
// Default to MB
return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
}
}

4. Usage in Template

Now you can use the name defined in the decorator (formatFileSize) in any HTML file:

<p>{{ 1048576 | formatFileSize }}</p>

<p>{{ 1048576 | formatFileSize:'KB' }}</p>

Useful CLI Flags

When generating pipes, you can use these flags to control the output:

FlagDescription
--flat(Default: true) Prevents the CLI from creating a sub-folder for the pipe.
--skip-testsSkips generating the .spec.ts (unit test) file.
--standaloneEnsures the pipe is generated as a Standalone component (default in newer Angular versions).
--projectSpecifies which project in a multi-project workspace to add the pipe to.


Share this lesson: