JavaScript Event composedPath() Method

Beginner
5 min read
Updated: Nov 2026
5 examples
Method

Definition

event.composedPath() returns an array of EventTarget objects on which listeners will be invoked (MDN) — the event’s path through the DOM (and shadow trees when allowed).

Pass the required arguments shown below. Check return values and browser support before you rely on the result.

Syntax

Call event.composedPath. Start with this line.

JavaScript
event.composedPath()
CallWhat it does
event.composedPath()Primary signature.
event.composedPath(...)Call with the arguments your case needs.

Built into the browser. Call composedPath(...) on an Event instance — no import required.

Library declarations
JavaScript
event.composedPath()

Parameters

This member has no parameters beyond those shown in the signature.

Return Value

Return ValueDescription
*EventTarget[]

JavaScript Examples

Example 1 — Log Path Tags

Map composedPath() to simple labels for debugging.

JavaScript
document.addEventListener("click", (e) => {
  const labels = e.composedPath().map((n) => {
    if (n === window) return "window";
    if (n === document) return "document";
    if (n instanceof Element) {
      return n.id ? "#" + n.id : n.tagName.toLowerCase();
    }
    return n.constructor.name;
  });
  console.log(labels.join(" → "));
});
Try It Yourself

How It Works

  1. Listen for click. Any click on the page reaches this handler if it bubbles.
  2. Call composedPath. Get the full EventTarget array.
  3. Map labels. Turn nodes into short names for the console.
  4. Read deepest first. Index 0 is usually the click origin.

Example 2 — Was the Click Inside a Panel?

Use path.includes(el) instead of walking parents by hand.

JavaScript
const panel = document.getElementById("panel");

document.addEventListener("click", (e) => {
  const path = e.composedPath();
  if (path.includes(panel)) {
    console.log("inside panel");
  } else {
    console.log("outside panel");
  }
});
Try It Yourself

How It Works

  1. Keep a panel reference. The node you care about.
  2. Build the path. Call composedPath() on the event.
  3. Use includes. True if that node is on the path.
  4. Outside clicks. Useful for closing menus / dialogs.

Example 3 — Open vs Closed Shadow

Outer listeners see different paths for open vs closed roots (MDN).

JavaScript
// open: path may include <p>, ShadowRoot, host, …
// closed: outer path typically starts at the host

document.documentElement.addEventListener("click", (e) => {
  console.log("composed:", e.composed);
  console.log(
    e.composedPath().map((n) =>
      n instanceof Element ? n.tagName.toLowerCase() : n.constructor.name
    )
  );
});
Try It Yourself

How It Works

  1. Click is composed. It can cross shadow boundaries.
  2. Open shadow. Outer path may list inner nodes + ShadowRoot.
  3. Closed shadow. Encapsulation hides inner nodes from the outer path.
  4. Host still appears. The custom element itself remains on the path.

Example 4 — path[0] vs event.target

Confirm the deepest path entry matches event.target on a normal click.

JavaScript
button.addEventListener("click", (e) => {
  const first = e.composedPath()[0];
  console.log(first === e.target); // usually true
});
Try It Yourself

How It Works

  1. Read path[0]. First entry is usually the deepest target.
  2. Compare to target. Same node for a simple button click.
  3. Prefer target for origin. Use the path when you need the full chain.
  4. Shadow caveat. Closed trees can change what outer code sees on the path.

Example 5 — Path Length

Log how many targets sit on the path for a nested click.

JavaScript
button.addEventListener("click", (e) => {
  const path = e.composedPath();
  console.log("length:", path.length);
  console.log("composed:", e.composed);
  console.log("target:", e.target.id);
});
Try It Yourself

How It Works

  1. Call composedPath. Get the full array once.
  2. Read length. Counts every target on that path.
  3. Pair with composed. Boolean boundary flag vs path size.
  4. Nesting grows the path. Deeper markup → larger array.

Browser Support

Event.composedPath() is marked Baseline Widely available on MDN (since January 2020). It is also available in Web Workers.

✓ Baseline · Widely available

Event.composedPath()

Returns EventTarget[] for the event path. Closed shadow roots omit inner nodes from the outer path. Pair with Event.composed for boundary behavior.

100% Widely available
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
composedPath() Excellent

Bottom line: Safe to use for debugging and inside-panel checks. Remember closed shadow encapsulation when working with web components.

Frequently Asked Questions

It returns an array of EventTarget objects on which listeners will be invoked for that event — the path the event travels through the DOM (and shadow trees when allowed).
No. MDN marks Event.composedPath() as Baseline Widely available (since January 2020). It is not Deprecated, Experimental, or Non-standard. It is also available in Web Workers.
composed says whether the event can cross a shadow boundary. composedPath() shows the actual objects on the path. For closed shadow roots, inner nodes may be omitted from the path you see outside.
Often yes for a normal click: the first entry is the deepest target. Prefer event.target for the origin, and composedPath() when you need the full chain.
If a shadow root was created with mode: "closed", composedPath() does not include nodes inside that closed tree when observed from outside — only as far as the host element.
Debugging event flow, web components, checking whether a click happened inside a specific ancestor (path.includes(el)), or comparing open vs closed shadow encapsulation.

Next: initEvent()

Learn the related Event initEvent() method.

initEvent tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful