Angular DevTools
On this page ▾
Every component instance on the page, in DOM order. Hover a row to find it in the page. Select it to read its live inputs, properties, outputs and injected services.

Components

The Components tab lists each rendered component instance as a tree. It walks each app root in document order, including shadow roots, then the components outside the app root, such as overlays. When no page is connected, it lists what your source declares instead.

What it shows

The tree

Each row shows the class name and the host tag. Routed components get a chip with their route path. A +N chip means N directives sit on the same host.

  • Filter by class, tag or directive name.
  • The toolbar counts the instances on the page. While you filter, it shows how many instances match, like 2 of 40. Ancestors kept to show where a match sits don't count.
  • Hover or focus a row to highlight its host element in the page.
  • Click a row, or press Enter or Space, to select it. Click it again to clear the selection.
  • Pick component on page selects the component behind an element you click in the app. See Pick a component on the page.

Screen readers hear the match count when the filter changes. Components that the app adds or removes are not announced.

Pages

When more than one tab reports, a Page menu picks the tab to show. The tab stays on the page you are looking at while other tabs report, and moves to another page only when yours closes. Opened from the popup or the Chrome extension, the tab starts on the page it belongs to.

Selection

The page keeps the selection, so the panel, the page and the agent tools share it. When highlight or inspect-component selects an instance, the panel selects it too. Each page keeps its own selection, and switching pages shows the selection of that page.

If the selected component is destroyed, for example by a route change or an item leaving a list, the detail pane says The selected component was destroyed and the selection clears. If the row had keyboard focus, focus moves to the next row, or to the row before it when the removed row was last.

The tree shows up to 2000 component instances, and walks up to 256 levels of DOM nesting. Past either limit, a notice names the limit, for example Showing the first 2000 component instances. Others are not listed or searchable., and the count reads 2000+ instances. The filter only searches the listed instances, so a component past the limit shows No components match. The inspect-component and highlight tools say the same when they find no match on a cut-off tree.

Detail header

The header of the selected instance shows the class name, the host tag, and the source file and line. The file and line come from the source scan, matched by class name. They are missing when the scan has no match.

When a form exists in the same source file, a Show … in Forms button opens it in the Forms tab.

Facts

  • Change detection: OnPush or Eager.
  • Encapsulation: Emulated, None, ShadowDom or IsolatedShadowDom.
  • Host path: where the host element sits in the page, as the chain of component hosts from the root. When a component renders several hosts with the same tag, for example cards in a @for list wrapped in <li>, each one gets its position among them, like app-list > app-card[2].
  • Routed: for routed components, the route and the outlet that rendered it.

A fact shows Unknown when Angular does not report it.

Inputs, outputs and listeners

  • Inputs with their live values. Signal inputs are unwrapped. When a component input has an alias, the row shows both names.
  • Outputs, each marked listened or no listener.
  • DOM listeners on the host element. This block appears only when there are any.
  • One block per directive on the host, with its inputs and outputs.

Properties

Properties lists the component's other own fields: plain fields, state objects, signals and resources. It leaves out inputs, outputs, methods and injected services. Signals show their current value and a signal flag. A field that holds a resource() or httpResource() shows its status, value and error, with a resource flag.

Injected services

Injected lists each token the component class injects, with its flags and the injector that provided it. The block marks a token nobody provides as not provided. The block leaves out tokens that host directives inject. Use the Injectors tab for those.

Defer blocks

When the page renders @defer blocks, a Defer blocks list follows the tree. Each row shows the component whose template holds the block, its state (placeholder, loading, complete or error) and its triggers. With incremental hydration, a row also shows dehydrated or hydrated, and a hydrate never flag marks a block that stays as server HTML.

Hover or focus a row to highlight the block in the page. Click it to select the component that holds it. The list is hidden when the page renders no defer blocks, or when its Angular version has no util to read them.

Change detection

Below the tree and the defer blocks, the Change detection section records change detection cycles with Angular's profiler. Click Record, use the app, then click Stop recording. Clear empties the recording.

  • Slowest components: each component class with its check count, its self time (its own template and hooks, children excluded) and its slowest single check.
  • Latest cycles, newest first: the start time, the duration, how many components Angular checked, how many sync passes it ran, the output listener that ran before the cycle, and the slowest component in it.
  • Tree rows show how many times each instance was checked while recording.

Recording is off by default. While it is off, the page registers no profiler for it. The page keeps the last 200 cycles, set with limits.cdCycles. Recording needs Angular 20 or later. On older versions, the section says so. Times come from a development build, so they are higher than in production.

Source mode

Without live data, the tab lists the @Component and @Directive classes in your source. Expand a row to see its class, file, standalone flag, change detection, inputs and outputs. Click Refresh to scan again.

For change detection, the scan reads the changeDetection key in the decorator. Without one, it uses the project's Angular version: OnPush from Angular 22, Eager before. It shows unknown when the value is an expression it can't read, or when the version can't be found.

A notice at the top says why you see the source list: no page is connected, or the page reported no instances.

Where the data comes from

The overlay walks the page with Angular's debug API after change detection. It doesn't resend an unchanged tree. After 8 seconds without a change, it sends a short ping so the server keeps the page. The server scans your files for @Component and @Directive classes. It also supplies the file and line in the detail header.

Debug APIs

The live tree reads window.ng, which only development builds expose. It uses these functions:

Function Used for
ng.getComponent, ng.getDirectives Finding instances and the directives on each host.
ng.getDirectiveMetadata Inputs, outputs, change detection and encapsulation.
ng.isSignal Unwrapping signal inputs.
ng.getListeners Output listeners and DOM listeners.
ng.getInjector, ɵgetDependenciesFromInjectable, ɵgetInjectorMetadata The Injected block, and the services Properties leaves out.
ng.ɵgetControlFlowBlocks, or ng.ɵgetDeferBlocks before Angular 22 The Defer blocks list.

Refresh rate

On Angular 20 and later, the page reads the tree about 250 ms after Angular runs change detection, and every 4 seconds as a heartbeat. Until the app bootstraps, it reads the tree every 3 seconds. It also reads it at once when you select an instance. It reads the detail block only for the selected instance. The server drops a page after 15 seconds without a report, unless its tab is in the background. See Tabs in the background.

How to use it

Find a component in the page

Type part of the class, tag or directive name. The page highlights each host element as you move over it. Click the row to open its details.

Pick a component on the page

Click Pick component on page. The floating panel fades so it doesn't cover the app. The page highlights the component under the pointer. The tab selects the component that hosts the element you clicked, and opens its details.

Press Escape, in the app or in the panel, or click Cancel pick to stop. Picking also stops after 15 seconds.

Start from the Elements panel

If you use the Chrome extension, open the Components tab in its panel. Then select an element in the Chrome Elements panel. The tab selects the component that hosts that element and scrolls its row into view.

Check why an output does nothing

Pick the component that declares the output. An output marked no listener has no parent binding. Check the parent template.

Track down a missing provider

Open the component that throws. A token marked not provided is the one to fix. Open the Injectors tab to see where Angular searched.

Keyboard

Use the arrow keys, Home and End to move through the tree. The right arrow expands a row or moves to its first child. The left arrow collapses a row or moves to its parent.

Agent tools

Tool or resource Kind What it does
ng-devtools:get-components tool Lists components and directives from source, with selector, kind, inputs, outputs, change detection, file and line.
ng-devtools:highlight tool Highlights a component in the page and selects it. Takes an instance id, class name, host tag or CSS selector. Also retargets the Signals graph. Lists every instance a name matches.
ng-devtools:inspect-component tool Selects one instance and returns its live detail: inputs, outputs, properties, listeners, directives and injected services.
ng-devtools:defer-blocks tool Lists the @defer blocks of each page, and flags blocks that failed, blocks stuck on their placeholder and blocks still dehydrated.
ng-devtools:change-detection tool Starts, stops or clears a change detection recording, and returns the slowest and most often checked components and the latest cycles.
ng-devtools:component-tree resource The live tree per page, with the detail of the selected instance and the defer blocks.

See Tools and Resources.

Limits and gotchas

Development builds only

Live data reads window.ng. Production builds remove it, so the tab falls back to the source list.

Values are shortened

Input and property values stop at 3 levels of nesting, 30 keys or items, and 300 characters. Past that, the devtools cut the value and mark it. Each block lists up to 60 inputs, outputs, properties or listeners.

Secrets are redacted

The devtools replace inputs and properties with secret-looking names with [redacted]. They also redact JWTs and Bearer values inside strings. See what the devtools redact.

Instance ids change on reload

Instance ids change on every page load. Don't store them between sessions.

FAQ

No page is connected, or the connected page is a production build. Open the app in a development build with the overlay loaded. The detail header matches the class name against the source scan. Classes outside the scanned folders, or from libraries, have no match. Two directives sit on its host element. Select it to see one block per directive.

Where to next

The injector tree and the lookup path of each token. The live signal graph of one component. Every form on the page, with field state and errors. The script that reports the live page.