JavaScript Node getRootNode() Method

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Instance method

What You’ll Learn

The Node.getRootNode() method returns the root of the tree that contains a node. Learn Document vs ShadowRoot results, the composed option, and what happens for detached nodes.

01

Kind

Instance method

02

Returns

Root Node

03

In page

Often Document

04

Shadow

ShadowRoot default

05

composed

Cross shadow

06

Status

Baseline widely

Introduction

Every node lives in some tree. getRootNode() answers: “What is the top of my tree right now?” On a normal page that is usually the document. Inside shadow DOM it is usually the shadow root—unless you ask to look past it.

The optional { composed: true } flag is the key for shadow DOM: it returns a root beyond the shadow boundary (often still the page document).

💡
Beginner tip

Start with node.getRootNode() and check .nodeName or instanceof Document / ShadowRoot to see what you got.

Understanding getRootNode()

MDN: returns the context object’s root, optionally including the shadow root depending on options.

  • In a document — typically an HTMLDocument (#document).
  • In shadow DOM — the associated ShadowRoot when composed is false.
  • composed: true — a root beyond the shadow root (often the document).
  • Detached tree — the top node of that fragment (may be the element itself).

📝 Syntax

JavaScript
const root = node.getRootNode();
const beyondShadow = node.getRootNode({ composed: true });

Parameters

  • options (optional) — Object with:
    • composedfalse (default) may return the shadow root; true looks beyond the shadow root.

Return value

An object inheriting from Node—commonly a Document, ShadowRoot, or the top Element of a detached tree.

🎨 The composed Option

CallTypical result for a shadow child
getRootNode()The ShadowRoot
getRootNode({ composed: false })Same as default — ShadowRoot
getRootNode({ composed: true })Root beyond shadow (often #document)

For light-DOM nodes with no shadow involved, composed usually does not change the result: you still get the document.

⚡ Quick Reference

GoalCode
Page document rootel.getRootNode() → often document
Shadow root of a nodeshadowChild.getRootNode()
Escape shadow to documentshadowChild.getRootNode({ composed: true })
Detached tree rootchild.getRootNode() → top parent
Is this the root?node === node.getRootNode()
MDN statusBaseline Widely available (since January 2020)

🔍 At a Glance

Four facts to remember about Node.getRootNode().

Returns
Node (root)

Doc / shadow / top

Baseline
widely

Since Jan 2020

Default
composed:false

Stops at shadow

composed:true
beyond shadow

Often document

Examples Gallery

Examples follow MDN Node.getRootNode() patterns. Use View Output or Try It Yourself for each case.

📚 Getting Started

Page documents and trees that are not attached yet.

Example 1 — Root of a Page Element Is the Document

MDN-style: a normal element’s root is the HTML document.

JavaScript
const child = document.querySelector(".child");
const root = child.getRootNode();

console.log(root.nodeName);      // "#document"
console.log(root === document);  // true
Try It Yourself

How It Works

Walking parents from the element reaches the document node that owns the page tree.

Example 2 — Detached Tree Root

Nodes not in the document still have a tree root.

JavaScript
const element = document.createElement("p");
const child = document.createElement("span");
element.append(child);

const rootNode = child.getRootNode();
console.log(element === rootNode);              // true
console.log(element === element.getRootNode()); // true
Try It Yourself

How It Works

MDN: element has no parent, so it is the root of that small tree. The child’s root is that parent <p>.

📈 Shadow DOM & Self-as-Root

Default shadow root, composed: true, and identity checks.

Example 3 — Shadow Child Roots at the ShadowRoot

Default composed stops at the shadow boundary.

JavaScript
const host = document.querySelector(".shadowHost");
const shadowRoot = host.attachShadow({ mode: "open" });
shadowRoot.innerHTML = '<div class="shadowChild">shadowChild</div>';
const shadowChild = shadowRoot.querySelector(".shadowChild");

console.log(shadowChild.getRootNode() === shadowRoot); // true
Try It Yourself

How It Works

Inside an open shadow tree, the default root is that ShadowRoot, not the outer document.

Example 4 — composed: true Crosses the Shadow

Ask for a root beyond the shadow root.

JavaScript
// assuming shadowChild from a shadow tree (see Example 3)
console.log(
  shadowChild.getRootNode({ composed: false }) === shadowRoot
); // true

console.log(
  shadowChild.getRootNode({ composed: true }).nodeName
); // "#document"
Try It Yourself

How It Works

MDN’s shadow example: composed: true returns the document node name #document while the default stays on the shadow root.

Example 5 — Top Node Equals Its Own Root

Handy check: am I the root of my tree?

JavaScript
const orphan = document.createElement("div");
console.log(orphan === orphan.getRootNode()); // true

const inPage = document.body;
console.log(inPage === inPage.getRootNode()); // false (root is document)
Try It Yourself

How It Works

A parentless node is its own root. Nodes under document have a higher root, so identity fails.

🚀 Common Use Cases

  • Detect whether a node lives in the main document or a shadow tree.
  • Resolve the correct root for queries scoped to a shadow root.
  • Use composed: true when you need the page document from inside shadow DOM.
  • Inspect detached fragments before they are appended.
  • Feature-detect tree context in web components and design systems.

🔧 How It Works

1

Start at the node

Call getRootNode with optional { composed }.

Call
2

Walk toward the top

Follow parents until the tree root for this context.

Climb
3

Respect shadow / composed

Default stops at ShadowRoot; composed true may continue.

Boundary
4

Return the root Node

Document, ShadowRoot, or detached top element.

📝 Notes

Universal Browser Support

Node.getRootNode() is Baseline Widely available across modern browsers (MDN: since January 2020). Logos use the shared browser-image-sprite.png sprite from this project.

Baseline · Widely available

Node.getRootNode()

Safe for production. Use composed: true when you need the document from inside shadow DOM.

Universal Widely available
Google Chrome Full support · Desktop & Mobile
Full support
Mozilla Firefox Full support · Desktop & Mobile
Full support
Apple Safari Full support · macOS & iOS
Full support
Microsoft Edge Full support · Chromium Edge
Full support
Opera Full support · Modern versions
Full support
Internet Explorer Not supported in legacy IE
No support
getRootNode() Excellent

Bottom line: Default root may be Document or ShadowRoot; composed true crosses the shadow boundary.

Conclusion

Node.getRootNode() returns the root of a node’s current tree. Know the Document vs ShadowRoot cases, use composed: true to look past shadow DOM, and remember detached trees root at their topmost node.

Continue with hasChildNodes(), contains(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Use getRootNode() to learn a node’s tree context
  • Pass { composed: true } when you need the outer document
  • Check instanceof ShadowRoot / Document on the result
  • Handle detached fragments before append
  • Prefer this over manual parent loops

❌ Don’t

  • Assume the root is always document
  • Forget default composed: false inside shadow DOM
  • Confuse getRootNode with ownerDocument
  • Confuse DOM Node with the Node.js runtime
  • Rely on IE—this API is modern Baseline

Key Takeaways

Knowledge Unlocked

Five things to remember about getRootNode()

Find the root of the tree that currently holds a node.

5
Core concepts
📄 02

Often Document

in the page

Light DOM
🎨 03

ShadowRoot

default in shadow

Shadow
04

composed:true

beyond shadow

Option
🔗 05

Detached

top node is root

Fragment

❓ Frequently Asked Questions

It returns the root of the tree that contains the node — typically the Document for nodes in a page, a ShadowRoot for nodes inside shadow DOM (by default), or the top node of a detached tree.
No. MDN marks Node.getRootNode() as Baseline Widely available (since January 2020). It is a standard DOM method — not Deprecated, Experimental, or Non-standard.
With composed: false (default), getRootNode stops at a shadow root. With composed: true, it crosses the shadow boundary and returns a root beyond the shadow root (often the document).
An HTMLDocument representing the page (nodeName is often #document).
It returns the root of the DOM tree they belong to. If an element has no parent, that element is its own root.
ownerDocument is the Document that created the node. getRootNode walks parents to the current tree root, which may be a ShadowRoot or a detached fragment root — not always the same as ownerDocument.
Did you know?

MDN’s Baseline date for getRootNode() is January 2020—newer than many classic Node APIs from 2015—because shadow DOM and composed roots matured later across browsers.

Next: hasChildNodes()

Check whether a node has any child nodes (including text).

hasChildNodes() →

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.

5 people found this page helpful