Node.getRootNode() returns the root of the tree that contains the node — usually the Document, or a ShadowRoot when the node lives in shadow DOM (MDN). An optional composed flag can cross the shadow boundary.
Baseline · Widely available: not Deprecated, Experimental, or Non-standard (since about January 2020).
Remember
node.getRootNode()
node.getRootNode({ composed: true })
in a normal page → #document (HTMLDocument)
inside shadow DOM → ShadowRoot (default)
composed: true → root beyond the shadow (often #document)
detached tree → top node of that tree (may be itself)
Use
Prefer
Page / light DOM root
node.getRootNode()
Stay inside shadow
default (composed: false)
Cross shadow boundary
getRootNode({ composed: true })
Approach
How to Use getRootNode()
Call it on any node; pass { composed: true } only when you need to escape a shadow tree.
Call node.getRootNode() with no options for the default root.
Inspect root.nodeName or compare with document / a ShadowRoot.
For shadow children, default root is the ShadowRoot.
Use { composed: true } to climb past the shadow root (often to the document).
Piece
Required?
Role
Receiver node
Yes
Any Node in a tree
options.composed
No (default false)
Cross shadow boundary when true
Return value
—
A Node (Document, ShadowRoot, …)
Pseudocode
Pseudocode
function getRootNode(node, composed = false):
walk toward parents / hosts
if hit ShadowRoot and composed is false:
return that ShadowRoot
if composed is true:
keep walking past the shadow host
return the outermost root
(#document, ShadowRoot, or detached top node)
Reference
Cheat Sheet
Keep these facts handy when resolving document vs shadow roots.
getRootNode(). Top of the tree the node is in now.
Detached case. Root is p, not document.
Pick the right API. Creation vs current tree membership.
Edge Cases & Pitfalls
Check these before assuming every root is document.
shadow
Default stops at ShadowRoot
Forgetting composed: true is the usual surprise when you expected the document.
detached
Detached roots are not documents
An unmounted top element is its own root until you append it into the page.
owner
Not the same as ownerDocument
Creation document vs current tree root — use the API that matches your question.
closed
Closed shadow mode
You still get a ShadowRoot from inside; outside scripts may not hold a reference when mode is closed.
Compatibility
Browser Support
Node.getRootNode() is Baseline Widely available (MDN, since about January 2020). Safe for modern shadow-aware DOM code.
✓ Baseline · Widely available
Node.getRootNode()
Supported in modern Chrome, Firefox, Safari, Edge, and Opera. Includes the composed option for shadow trees.
96%Modern browser support
Google ChromegetRootNode() · composed
Full support
Microsoft EdgegetRootNode() · Chromium
Full support
Apple SafarigetRootNode() · modern versions
Full support
Mozilla FirefoxgetRootNode() · modern versions
Full support
OperagetRootNode() · modern versions
Full support
Internet ExplorerNo getRootNode()
Unavailable
Node.getRootNode()Excellent
Bottom line: Use freely in modern apps. Prefer composed: true only when you intentionally need the outer root.
Analysis
Performance Notes
Approach
Cost
Best for
getRootNode() once
Cheap
Event / setup checks
Manual parent walk
More code
Rarely better
Call every frame
Wasteful
Avoid — cache when the tree is stable
Resolve the root when the tree changes (attach, move, open shadow) — not in a tight animation loop.
Remember
Key Takeaways
Role: return the root of the node’s current tree.
Default: Document in the page; ShadowRoot inside shadow.
composed: true: climb past the shadow root.
Detached: top node with no parent is its own root.
One line:getRootNode() finds where a node’s tree starts — document, shadow root, or a detached top.
Frequently Asked Questions
The root of the tree that contains the node — typically the Document for page nodes, a ShadowRoot inside shadow DOM (by default), or the top node of a detached tree (MDN).
No. MDN marks it Baseline Widely available (since about January 2020). It is not Deprecated, Experimental, or Non-standard.
composed: false (default) stops at a shadow root. composed: true crosses the shadow boundary and returns a root beyond it (often the document).
An HTMLDocument for the page (nodeName is often #document).
It returns the root of that DOM tree. If an element has no parent, that element is its own root (MDN Example 3).
ownerDocument is the Document that created the node. getRootNode walks to the current tree root, which may be a ShadowRoot or a detached fragment root.