On this page ▾
Pipes
The Pipes tab lists your @Pipe classes and the built-in pipes from @angular/common that your templates use. It shows the live instances on the page, and records calls when you ask it to.
What it shows
Pipe list
Search by pipe name, class or file. Narrow the list with Show pipes: All pipes, Custom, Built-in, Impure or On the page.
Each row shows the pipe name, its class, and chips:
- N live: instances on the page.
- built-in, and NgModule for pipes that are not standalone.
- pure or impure.
- stale? when recording caught a possible stale value.
Hover or focus a row to highlight the first component that uses it.
Declaration
Select a pipe to see its class, whether it comes from @angular/common or your project, its file, and whether it is standalone and pure. A pure pipe reruns only when an argument changes. An impure pipe reruns on every check.
Used in templates
For built-in pipes, every template that uses it, with file and line. The scan reads interpolations, bound attributes, @if, @else if, @for, @switch and @case conditions, @defer triggers and @let values.
Live on the page
The number of instances and the components that use them. Click, hover or focus a component chip to highlight it. With recording on, this block adds the call count, the last input and output, a per-instance breakdown and the last caller.
Async subscriptions
When templates use | async, the tab lists each subscription with its component and latest value. This needs no recording. Each | async subscribes on its own. Two on the same source run the work twice, so the tab marks those rows duplicate subscription.
A source that changes on three reports in a row, like getData() | async returning a new Observable on each check, is marked resubscribing. AsyncPipe unsubscribes and subscribes again every time the source changes, so with HttpClient each check sends a request. A method that returns the same Observable each time is not marked.
Lint
| Rule | Severity | Finds |
|---|---|---|
impure-pipe-in-for |
warning | An impure pipe inside an @for block. It runs on every check, possibly once per row. |
json-pipe-in-template |
info | | json left in a template. It is a debugging aid. |
signal-read-in-pure-pipe |
warning, info | A pure pipe whose transform() reads a signal, input, computed, linkedSignal, toSignal or model field of the pipe (warning). A call with no arguments on an injected service, like this.rates.current(), might be a signal read (info). |
async-on-call |
info | A method call piped to | async, like getUsers() | async. If the method builds a new Observable each time, AsyncPipe resubscribes on every check. Signal, input, computed and toSignal fields of the component are skipped. |
Where the data comes from
@Pipe classes with name, class, file, standalone and pure flags. Built-in pipes with every usage site.
Built-in pipes
The built-in list covers the @angular/common pipes: async, currency, date, number, i18nPlural, i18nSelect, json, keyvalue, lowercase, percent, slice, titlecase and uppercase. Pipes from other packages are not listed as built-in.
Live instances
Live discovery walks the rendered views with ng.getComponent and related debug helpers. It needs a development build.
Recording
Click Record calls to count calls and keep the last input and output of each pipe. Recording patches each pipe's transform in the inspected page, on every connected tab. It covers the pipes found on the page. Click Stop recording when you are done.
Each recording starts from zero, so a second recording measures one interaction on its own. The button switches to Stop recording once a page confirms that it is recording. If no page is connected, the tab says so and stays on Record calls.
How to use it
Find a slow pipe
computed().
Find a stale value
Date, Map and Set values are compared. The chip clears once the pipe reruns.
Remove duplicate subscriptions
Open Async subscriptions and look for duplicate subscription rows. Subscribe once with @let, or turn the observable into a signal with toSignal().
Stop resubscribing
Look for resubscribing rows in Async subscriptions, and for async-on-call in Lint. Keep the Observable in a field, or read it with toSignal() or httpResource().
Agent tools
| Tool | Live | What it does |
|---|---|---|
ng-devtools:get-pipes |
no | Custom pipes and the built-in pipes in use. |
ng-devtools:lint-pipes |
no | Runs the lint rules above. |
ng-devtools:explain-pipe |
partly | One pipe by name: where it is declared or used, purity, live counts, last input and output, the stale warning, resubscribing | async usages and the lint findings. |
Agents can't turn recording on. To give explain-pipe call data, click Record calls in the panel first. See Tools.
Limits and gotchas
json pipe, is parsed and redacted too, and shown without its line breaks. See Access and redaction.
The stale warning is experimental
It runs only while recording. It reads the template source, so it needs an unminified development build. When it can't read the template, it stays quiet. It compares the first two levels of an argument and up to 50 items per level.
Signal reads on services are a guess
signal-read-in-pure-pipe can't tell a signal on an injected service from a method with no arguments, so it reports those calls at info level.
Recording ends on reload
Recording is off by default. Reload the page and it is off again.
FAQ
@angular/common pipes only.