JavaScript appendChild() — add and move DOM nodes

Tech reviewed: Deepak Prasad
JavaScript appendChild() — add and move DOM nodes

Node.prototype.appendChild inserts a node as the last child of a parent element—or moves an existing node from its old parent into the new one, because a node can only have one parent at a time. The usual flow is create with document.createElement, set properties or textContent, then append. For sibling-specific ordering or inserting before a known child, pair this with JavaScript insertBefore; for multiple nodes at once, consider a DocumentFragment.

The console.log lines below were captured with Node.js v20.18.2 and jsdom 24.0.0, which implements the same DOM APIs browsers expose on document. To reproduce them, run npm install [email protected] in a folder and execute each script with node. In a real HTML page, skip the JSDOM bootstrap and run the DOM portion in a <script> or DevTools where document already exists.

Tested on: Node.js v20.18.2 and jsdom 24.0.0; fenced text output below each snippet is the exact console output from that run.


Quick reference

Use this table for javascript appendchild vs append and related DOM moves.

Goal API
One child at the end; need return value parent.appendChild(node)
Multiple nodes or raw strings parent.append(...)
Batch insert (nodes “lifted” into parent) DocumentFragment + parent.appendChild(fragment)
Insert before a specific sibling parent.insertBefore(newNode, referenceChild)
Keep source subtree in place cloneNode(true) then append the clone

1. Basic appendChild (javascript appendchild)

Diagram: DOM tree before and after appendChild adds a new last child under the parent

Select a parent (for example with document.getElementById or querySelector), create a child, set its text, then append.

javascript
const { JSDOM } = require("jsdom");

const { document } = new JSDOM(
  `<!DOCTYPE html><html><body><div id="parent"></div></body></html>`,
).window;

const parent = document.getElementById("parent");
const child = document.createElement("p");
child.textContent = "Welcome Home";

const returned = parent.appendChild(child);

console.log(parent.innerHTML);
console.log(returned === child);
text
<p>Welcome Home</p>
true

The first line is parent.innerHTML after the insert. The second line shows appendChild returns the same node you passed in—useful for chaining.


2. Append another list item (appendchild on a <ul>)

appendchild javascript tutorials often use a list: new li nodes are added after existing children.

javascript
const { JSDOM } = require("jsdom");

const { document } = new JSDOM(
  `<!DOCTYPE html><html><body>
    <ul id="list"><li>HTML</li><li>CSS</li><li>JS</li></ul>
  </body></html>`,
).window;

const list = document.getElementById("list");
const item = document.createElement("li");
item.textContent = "Python";

list.appendChild(item);

console.log(list.innerHTML.replace(/\s+/g, " ").trim());
text
<li>HTML</li><li>CSS</li><li>JS</li><li>Python</li>

3. Moving an existing node (not a copy)

If the node already has a parent, appendChild in JavaScript moves it: the old parent loses the subtree at that branch.

javascript
const { JSDOM } = require("jsdom");

const { document } = new JSDOM(
  `<!DOCTYPE html><html><body>
    <div id="oldParent"><p id="child">Holder Value</p></div>
    <div id="parent1"></div>
  </body></html>`,
).window;

const parent1 = document.getElementById("parent1");
const child = document.getElementById("child");

parent1.appendChild(child);

const oldParent = document.getElementById("oldParent");

console.log("old:", oldParent.innerHTML.replace(/\s+/g, " ").trim());
console.log("new:", parent1.innerHTML.replace(/\s+/g, " ").trim());
text
old:
new: <p id="child">Holder Value</p>

To duplicate instead of move, use cloneNode(true) and append the clone (duplicate id attributes are invalid in real pages—assign a new id when needed).

javascript
const { JSDOM } = require("jsdom");

const { document } = new JSDOM(
  `<!DOCTYPE html><html><body>
    <div id="p1"></div><div id="p2"></div>
  </body></html>`,
).window;

const p1 = document.getElementById("p1");
const p2 = document.getElementById("p2");
const span = document.createElement("span");
span.textContent = "x";

p1.appendChild(span);
const copy = span.cloneNode(true);
p2.appendChild(copy);

console.log("p1:", p1.innerHTML);
console.log("p2:", p2.innerHTML);
console.log("same object:", span === copy);
text
p1: <span>x</span>
p2: <span>x</span>
same object: false

4. append vs appendChild (js appendchild vs modern append)

For javascript appendchild html-style ergonomics, compare Element.append: it accepts strings (converted to Text nodes) and multiple arguments, while appendChild only accepts one Node.

javascript
const { JSDOM } = require("jsdom");

const { document } = new JSDOM(
  `<!DOCTYPE html><html><body><div id="box"></div></body></html>`,
).window;

const box = document.getElementById("box");
const span = document.createElement("span");
span.textContent = "a";

box.appendChild(span);
box.append(" ", "b");

console.log(JSON.stringify(box.innerHTML));
text
"<span>a</span> b"

5. DocumentFragment: several nodes, one appendChild

appendChild js patterns for batch insert: build a DocumentFragment, append multiple children to the fragment, then parent.appendChild(fragment). The fragment empties—its children become the parent’s children.

javascript
const { JSDOM } = require("jsdom");

const { document } = new JSDOM(
  `<!DOCTYPE html><html><body><div id="root"></div></body></html>`,
).window;

const root = document.getElementById("root");
const frag = document.createDocumentFragment();

frag.appendChild(document.createElement("span")).textContent = "1";
frag.appendChild(document.createElement("span")).textContent = "2";

root.appendChild(frag);

console.log("fragment children after append:", frag.childNodes.length);
console.log(root.innerHTML);
text
fragment children after append: 0
<span>1</span><span>2</span>

6. Inserting before the end — insertBefore

appendChild cannot place a node in the middle; use insertBefore(newNode, referenceNode).

javascript
const { JSDOM } = require("jsdom");

const { document } = new JSDOM(
  `<!DOCTYPE html><html><body>
    <ul id="u"><li id="a">A</li><li id="b">B</li></ul>
  </body></html>`,
).window;

const ul = document.getElementById("u");
const li = document.createElement("li");
li.textContent = "mid";

ul.insertBefore(li, document.getElementById("b"));

console.log(ul.innerHTML.replace(/\s+/g, " ").trim());
text
<li id="a">A</li><li>mid</li><li id="b">B</li>

7. Security note (javascript appendchild html)

Prefer createElement plus textContent / appendChild for structured UI. Treat innerHTML and insertAdjacentHTML as HTML parsers: unsafe with untrusted strings. After nodes exist, you can wire behavior with addEventListener.


Summary

  • appendChild adds one Node as the last child and returns it; if the node was mounted elsewhere, it moves.
  • Use append for multiple arguments or string children; use DocumentFragment to batch several elements in one append.
  • Use insertBefore for ordering; use cloneNode(true) when you must not move the original.

References

MDN entries for appendChild, append, and related node APIs.


Frequently Asked Questions

1. What does JavaScript appendChild do?

Node.appendChild(child) inserts child as the last child of the parent. If child was already somewhere in the document, it is moved—not copied. The method returns the appended child node, or throws TypeError if the argument is not a Node (for example null).

2. What is the difference between append and appendChild in JavaScript?

appendChild accepts exactly one Node and returns that node. Element.append can take multiple Node or string arguments; strings become Text nodes. append returns undefined. Use appendChild when you need the return value or maximal older-browser compatibility; use append for ergonomic multi-insert and raw text.

3. Is appendChild the same as innerHTML for adding children?

No. innerHTML parses HTML strings and replaces or builds markup, which is risky with untrusted input and can drop event listeners when you reassign wholesale. appendChild attaches an existing Node you created with createElement (or moved from elsewhere)—no HTML parser involved.

4. How do I add a child in JavaScript without moving an existing node?

Call element.cloneNode(true) to duplicate a subtree, then appendChild the clone. Moving still happens if you appendChild the original node while it already has a parent.

5. Can appendChild add more than one element at once?

Only one Node per call, but you can appendChild a DocumentFragment; its children are transferred into the parent in document order and the fragment becomes empty.

6. How do I insert a node somewhere other than the end?

Use parent.insertBefore(newNode, referenceChild). appendChild always appends after the current last child.
Olorunfemi Akinlua

Boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs user-friendly interfaces to enhance digital …

  • JavaScript
  • Web Design