JavaScript Node cloneNode() Method

Beginner
6 min read
Updated: Oct 2026
5 examples
Live preview

What Is cloneNode()?

node.cloneNode(deep) returns a duplicate of the node (MDN). Pass true to copy the whole subtree; omit or pass false for a shallow copy.

Status: Baseline Widely available (since July 2015) — not Deprecated, Experimental, or Non-standard. Warning: clones can duplicate id values — rename before inserting.

Remember
node.cloneNode()       → shallow (node only; default deep=false)
node.cloneNode(true)   → deep (node + descendants)

Copies attributes (incl. inline onclick="...")
Does NOT copy addEventListener / node.onclick = fn

Clone has no parent until you appendChild / insertBefore
Same document + same id → fix the clone's id
GoalPrefer
Copy in same documentcloneNode(true|false)
Copy into another document / templatesimportNode()
Insert the copyappendChild()

How to Use cloneNode()

Clone, optionally fix id, then insert the copy into the tree.

  1. Select the node to copy.
  2. Call cloneNode(true) (deep) or cloneNode() (shallow).
  3. Change duplicate id / name if needed.
  4. Insert with appendChild (or similar).
PieceRequired?Role
deepNotrue = subtree; default false
Return—New Node (not in the document yet)
Listeners—Inline attrs yes; addEventListener no

Pseudocode

Pseudocode
original = getElementById("card")
copy = original.cloneNode(true)   // deep

if copy.id:
  copy.id = "card-2"              // avoid duplicate ids

parent.appendChild(copy)
→ original stays; copy is a new sibling/subtree

Cheat Sheet

Keep these facts handy when copying DOM nodes.

TopicDetail
Syntaxnode.cloneNode() / node.cloneNode(deep)
Default deepfalse (shallow)
ReturnsDetached clone (no parent yet)
AttributesCopied (including inline handlers)
JS listenersNot copied (addEventListener / onclick =)
IDsMay duplicate — rename the clone
vs importNodeOther document / template custom elements
StandardBaseline Widely available (since July 2015)

Live Preview

Clone the sample card shallow or deep, then append the copy to the list.

Source
Card title · child text

Browser demo of Node.cloneNode() — deep vs shallow.

Result
Choose deep or shallow, then Clone…

JavaScript Examples

Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.

Example 1 — Deep Clone

MDN-style: copy the node and its subtree.

JavaScript
const p = document.getElementById("para1");
const p2 = p.cloneNode(true);
console.log(p2.textContent);
Try It Yourself

How It Works

  1. Select the source. Any node in the document.
  2. Pass true. Deep copy includes descendants / text.
  3. Read textContent. Matches the original subtree.
  4. Still detached. Append later to show it on the page.

Example 2 — Shallow Clone

Default / false: element shell only — no children.

JavaScript
const card = document.getElementById("card");
const shell = card.cloneNode(false);

console.log(shell.childNodes.length); // 0
console.log(shell.className);         // attributes kept
Try It Yourself

How It Works

  1. Omit deep or pass false. Only the node itself.
  2. Attributes remain. Class, id, data-* copy over.
  3. No subtree. Inner text / children are missing.
  4. Void elements. deep has little effect (MDN).

Example 3 — Avoid Duplicate IDs

MDN warning: rename id before inserting into the same document.

JavaScript
const original = document.getElementById("item");
const copy = original.cloneNode(true);
copy.id = "item-2";
document.getElementById("list").appendChild(copy);
Try It Yourself

How It Works

  1. Deep-clone the item. Copy includes the old id.
  2. Assign a new id. Keep the document unique.
  3. Append the copy. Both nodes can coexist safely.
  4. Check names too when forms use duplicate name.

Example 4 — Listeners Are Not Copied

addEventListener stays on the original only (MDN).

JavaScript
const btn = document.getElementById("btn");
btn.addEventListener("click", () => console.log("hi"));

const copy = btn.cloneNode(true);
document.body.appendChild(copy);
// clicking copy does NOT log "hi" — re-bind if needed
Try It Yourself

How It Works

  1. Bind with addEventListener. Lives on the original node.
  2. Clone the button. Markup/attrs copy; JS listeners do not.
  3. Append the clone. Looks the same, acts differently.
  4. Re-attach handlers on the clone when you need them.

Example 5 — Clone Then Append

Typical workflow: deep clone + appendChild.

JavaScript
const list = document.getElementById("list");
const item = document.getElementById("item");

list.appendChild(item.cloneNode(true));
console.log(list.children.length);
Try It Yourself

How It Works

  1. Clone first. Creates a detached copy.
  2. Append the copy. Original stays where it was.
  3. Count children. Length grows by one.
  4. Unlike move: appendChild(item) alone would relocate.

Edge Cases & Pitfalls

Check these before cloning into a live document.

warning

Duplicate IDs

MDN: if the original has an id, change the clone’s id before inserting into the same document.

listeners

JS listeners are not copied

Inline attribute handlers copy; addEventListener and node.onclick = fn do not.

template

Prefer importNode for templates

MDN: for <template> content with custom elements, use document.importNode().

detached

Clone is not on the page yet

You must appendChild / insertBefore the clone yourself.

Browser Support

Node.cloneNode() is marked Baseline Widely available on MDN (since July 2015).

✓ Baseline · Widely available

Node.cloneNode()

Returns a duplicate node. deep=true copies the subtree. Attributes copy; addEventListener does not. Watch for duplicate IDs.

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
cloneNode() Excellent

Bottom line: Safe everyday DOM API. Rename ids, re-bind listeners, and use importNode for other documents / templates. See the MDN cloneNode reference.

Performance Notes

ApproachCostBest for
cloneNode(false)CheapEmpty shell / void elements
cloneNode(true)O(subtree size)Full UI card / list item
Many deep clonesCan be heavyBatch carefully / reuse templates

Deep clones walk the whole subtree. For repeated UI, clone a small template node rather than a huge branch every time.

Key Takeaways

  • Deep vs shallow: true copies descendants; default is shallow.
  • Detached: append the clone yourself.
  • IDs: rename clones in the same document.
  • Listeners: re-bind addEventListener on the clone.

One line: cloneNode copies a node (optionally its tree) — insert it, fix ids, re-bind JS listeners.

Frequently Asked Questions

It returns a duplicate of the node. With deep true, the whole subtree is copied; with false or omitted, only the node itself is cloned (no children).
No. MDN marks Node.cloneNode() as Baseline Widely available (since July 2015). It is not Deprecated, Experimental, or Non-standard.
It copies attributes, including inline handlers like onclick="...". It does not copy listeners added with addEventListener() or assigned via onevent properties such as node.onclick = fn.
If the original has an id and you insert the clone into the same document, you get two elements with the same id. Change the clone's id (and sometimes name) to stay unique.
Use document.importNode() when cloning into another document, or when cloning HTML template content that may include custom elements that should upgrade in the current document.
No. The clone has no parent until you insert it with appendChild, insertBefore, or a similar method.

Next: compareDocumentPosition()

Learn how two nodes relate in the document tree.

compareDocumentPosition 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