JavaScript Modifying the document
Learn how to modify the DOM with JavaScript: create, insert, replace and remove nodes, use insertAdjacentHTML, and batch updates with DocumentFragment.
JavaScript lets you change a page after it has loaded: add new elements, move them around, update text, swap attributes, and remove things the user no longer needs. This is the foundation of every dynamic interface — from showing a validation message to rendering a whole list of search results.
This page covers the practical toolkit for modifying the DOM: creating and inserting nodes, the difference between textContent and innerHTML, fast HTML insertion with insertAdjacentHTML, removing and replacing nodes, and using a DocumentFragment to keep updates fast. To find the elements you want to change first, see Searching: getElement* and querySelector*. For the bigger picture of how the page is structured as a tree of nodes, see Understanding the DOM nodes.
Creating new nodes
Before you can insert something into the page, you have to create it. There are two building blocks: element nodes (<div>, <li>, …) and text nodes (plain text).
Creating elements
New elements are created with the document.createElement(tag) method. The element exists only in memory until you insert it into the document — until then the user sees nothing. Here is how to create a div and add it to the page:
<body></body>
<script>
let div = document.createElement('div');
div.innerHTML = "Hello, world!";
document.body.appendChild(div);
</script>The element only appears once appendChild (or another insertion method) attaches it to a node that is already in the document.
Creating text nodes
To add plain text, use document.createTextNode(text). Unlike innerHTML, a text node treats its content literally — <b> stays the characters <b> instead of becoming a bold tag. That makes text nodes the safe choice when the text comes from a user or any untrusted source:
<body>
<div id="container"></div>
</body>
<script>
const div = document.getElementById("container");
let textNode = document.createTextNode('Here is some text');
div.appendChild(textNode);
</script>Inserting nodes
Once a node exists, you need to place it somewhere. The classic method is parent.appendChild(node), which adds the node as the last child. Modern browsers also provide a more flexible family of methods that accept either nodes or strings:
| Method | Where it inserts |
|---|---|
node.append(...) | At the end, inside node |
node.prepend(...) | At the start, inside node |
node.before(...) | Just before node |
node.after(...) | Just after node |
node.replaceWith(...) | Replaces node entirely |
Here append and prepend add list items to opposite ends of a <ul>:
<body>
<ul id="list">
<li>middle</li>
</ul>
</body>
<script>
const list = document.getElementById("list");
const first = document.createElement("li");
first.textContent = "first";
list.prepend(first);
const last = document.createElement("li");
last.textContent = "last";
list.append(last);
</script>insertAdjacentHTML
When you want to insert a string of HTML relative to an element — without disturbing the existing content — element.insertAdjacentHTML(position, html) is the tool. The position argument is one of four keywords:
"beforebegin"— before the element itself"afterbegin"— inside, before the first child"beforeend"— inside, after the last child"afterend"— after the element itself
<body>
<div id="box">existing content</div>
</body>
<script>
const box = document.getElementById("box");
box.insertAdjacentHTML("beforeend", "<p>added inside, at the end</p>");
box.insertAdjacentHTML("afterend", "<p>added after the box</p>");
</script>Because insertAdjacentHTML parses an HTML string, never pass untrusted input to it — the same XSS risk applies as with innerHTML. There are sibling methods insertAdjacentText and insertAdjacentElement for inserting plain text or an existing node in the same positions.
textContent vs innerHTML
Both properties set the contents of an element, but they behave very differently:
innerHTMLparses the string as HTML.el.innerHTML = "<b>Hi</b>"produces a bold node. Assigning to it replaces all existing children.textContenttreats the string as plain text.el.textContent = "<b>Hi</b>"shows the literal characters<b>Hi</b>.
Prefer textContent whenever you are inserting text — it is faster and immune to HTML/script injection. Reach for innerHTML only when you genuinely need markup and the source is trusted.
<body>
<div id="asHtml"></div>
<div id="asText"></div>
</body>
<script>
const input = "<b>3 < 5</b>";
document.getElementById("asHtml").innerHTML = input; // renders bold text
document.getElementById("asText").textContent = input; // shows the literal markup
</script>Modifying Elements
Changing Attributes
To change an attribute of an element, you can use element.setAttribute(name, value). This method allows you to set the value of an attribute on the specified element.
<body>
<div id="firstID"></div>
<div>new id is: <span id="result"></span></div>
</body>
<script>
const div = document.getElementById("firstID");
const result = document.getElementById("result");
div.setAttribute("id", "newDiv");
result.innerHTML = div.id;
</script>For a deeper look at the distinction between HTML attributes and DOM properties (and when to use setAttribute vs. direct property access like el.id = "..."), see Attributes and properties.
Advanced Manipulations
Cloning Elements
You can create a copy of an element by using the element.cloneNode(deep) method. Setting deep to true clones the element and its descendants.
<body>
<div id="mydiv">one div here, or two divs if cloned! <span>And here is a span inside the div!</span></div>
</body>
<script>
const div = document.getElementById("mydiv");
const clone = div.cloneNode(true);
document.body.appendChild(clone);
</script>Replacing Elements
To swap one node for another, call element.replaceWith(newNode). The old node leaves the document and the new one takes its place:
<body>
<p id="old">I will be replaced.</p>
</body>
<script>
const old = document.getElementById("old");
const fresh = document.createElement("p");
fresh.textContent = "I am the replacement.";
old.replaceWith(fresh);
</script>Removing Elements
To remove an element from the DOM, you can use element.remove().
<body>
<div>It's the only thing you see, as the next div is removed!</div>
<div id="mydiv">you don't see me if I'm removed!</div>
</body>
<script>
const div = document.getElementById("mydiv");
div.remove();
</script>Batching updates with a DocumentFragment
Every time you insert a node into the live document, the browser may recalculate layout. Inserting many nodes in a loop, one at a time, can therefore be slow. A DocumentFragment is a lightweight, off-screen container: you assemble all your nodes inside it, then insert the fragment once. Only its children end up in the DOM — the fragment itself disappears.
<body>
<ul id="list"></ul>
</body>
<script>
const list = document.getElementById("list");
const fragment = document.createDocumentFragment();
for (let i = 1; i <= 5; i++) {
const li = document.createElement("li");
li.textContent = "Item " + i;
fragment.appendChild(li);
}
// One single insertion into the live document
list.appendChild(fragment);
</script>For more ways to keep DOM updates efficient, see DOM performance optimization. If your markup is reusable, the <template> element is another fast way to clone ready-made structure.
Practical Example: Building a To-Do List
Let's apply these concepts to create a simple to-do list with JavaScript:
<body></body>
<script>
// Creating the list container
let list = document.createElement('ul');
document.body.appendChild(list);
// Adding items to the list
function addItem(text) {
let item = document.createElement('li');
item.textContent = text;
list.appendChild(item);
}
addItem('Learn JavaScript');
addItem('Build a to-do list');
</script>Conclusion
Modifying the document is the core of every dynamic interface: create nodes with createElement/createTextNode, place them with append/prepend/before/after or insertAdjacentHTML, choose textContent for safe text and innerHTML only for trusted markup, and use a DocumentFragment to keep bulk updates fast. Use replaceWith and remove to swap or drop nodes.
To go further, explore DOM manipulation for a broader overview, Traversing the DOM to move between related nodes, and Node properties: type, tag and contents to understand what each node holds.