The composedPath() method returns an array of EventTarget objects on which listeners will be invoked—the event’s path. Learn how it pairs with composed, why open vs closed shadow roots differ, and how to map the path for debugging—with five examples and try-it labs.
01
Kind
Instance method
02
Returns
EventTarget[]
03
Means
Listener path
04
Params
None
05
Pairs with
composed
06
Status
Baseline widely
Fundamentals
Introduction
When you click a nested button, the event does not only touch that button. It travels a path: the target, then parents, then document, then window (depending on the event).
event.composedPath() returns that path as an array. With Shadow DOM, the path can also include shadow nodes—unless the shadow root is closed, which hides internals from the path you see outside (as MDN demonstrates).
💡
Beginner tip
Call composedPath()inside a listener while the event is being dispatched. Map nodes with node.nodeName (or String(node) for Window) to print a readable chain.
Concept
Understanding Event.composedPath()
An instance method that returns the event’s path: an array of objects on which listeners will be invoked.
Return value — EventTarget[] along the dispatch path.
No parameters — call event.composedPath().
Shadow DOM — may include shadow nodes when the tree is open / visible on the path.
Closed roots — nodes inside a closed shadow tree are not included (path stops at the host from the outside).
Baseline Widely available on MDN (since January 2020); also in Web Workers.
Foundation
📝 Syntax
JavaScript
composedPath()
Parameters
None.
Return value
An array of EventTarget objects representing the objects on which an event listener will be invoked.
composed = true
P → #document-fragment → OPEN-SHADOW → BODY → …
How It Works
Open mode lets outside code see into the shadow path for composed events like click.
Example 5 — Closed Shadow Path (MDN Idea)
With mode: "closed", the path stops at the host—no inner p.
JavaScript
// Same click listener; closed-shadow hides internals:
// composedPath may look like:
// CLOSED-SHADOW → BODY → HTML → Document → Window
// (no P / ShadowRoot entries from outside)
Event.composedPath() is marked Baseline Widely available on MDN (since January 2020). Logos use the shared browser-image-sprite.png sprite from this project. It is also available in Web Workers.
✓ Baseline · Widely available
Event.composedPath()
Returns the event path as an array of EventTarget objects (shadow nodes may be omitted for closed roots).
UniversalWidely available
Google ChromeFull support · Desktop & Mobile
Full support
Mozilla FirefoxFull support · Desktop & Mobile
Full support
Apple SafariFull support · macOS & iOS
Full support
Microsoft EdgeFull support · Chromium
Full support
OperaFull support · Modern versions
Full support
Internet ExplorerNot supported (use modern browsers)
Unavailable
Event.composedPath()Excellent
Bottom line: Use composedPath() to see the full listener path—especially with Shadow DOM—and pair it with Event.composed.
Wrap Up
Conclusion
Event.composedPath() returns the array of targets on the event’s path. Use it to debug flow, check ancestors, and understand how open vs closed shadow trees change what you can see.
Mutate the returned array as if it owned the live tree
Skip testing open vs closed when shipping components
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about composedPath()
The event’s path as an EventTarget array.
5
Core concepts
📈01
Array
of targets
API
🎯02
path[0]
~ event.target
Origin
🎨03
composed
boundary flag
Pair
🔒04
Closed
hides internals
Shadow
🎯05
Baseline
since Jan 2020
Status
❓ 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.
Did you know?
For a composed click, event.composed is true for both open and closed shadow hosts—but composedPath() still differs. The boolean answers “can it cross?”; the method answers “what can I see on the path?”