Adding, removing, and mutating DOM elements in vanilla JS
TL;DR
The DOM gives you a small set of primitives: createElement to build nodes, append/appendChild to insert them, remove/removeChild to take them out, and a handful of APIs to change content and attributes. Master these and you can make any page dynamic without a framework.
Creating and inserting
// Create a new elementconst paragraph = document.createElement('p');paragraph.textContent = 'Hello, world!';paragraph.className = 'greeting';// Add it to the pagedocument.body.appendChild(paragraph);
Insertion alternatives worth knowing:
const container = document.querySelector('#container');// append — adds to the end (can add multiple items and text)container.append(element1, element2, 'some text');// prepend — adds to the beginningcontainer.prepend(element);// before / after — adds next to the elementexistingElement.before(newElement);existingElement.after(newElement);// insertAdjacentHTML — inserts HTML string at a specific positioncontainer.insertAdjacentHTML('beforeend','<p>New paragraph</p>');
append/prepend are the modern go-tos — they accept multiple nodes and raw strings, unlike the older appendChild.
Removing
// Modern way — call remove() on the elementconst element = document.querySelector('#old-item');element.remove();// Older way — remove through the parentconst parent = document.querySelector('#list');const child = document.querySelector('#old-item');parent.removeChild(child);
Mutating
Content:
element.textContent = 'New text'; // safe, plain textelement.innerHTML = '<strong>Bold</strong>'; // parses HTML
Reach for textContent by default — innerHTML with untrusted input is an XSS vector.
Attributes:
element.setAttribute('data-id', '42');element.getAttribute('data-id'); // "42"element.removeAttribute('data-id');// Or use properties directlyelement.id = 'my-element';element.className = 'active';
Inline styles:
element.style.color = 'red';element.style.fontSize = '16px';element.style.display = 'none';
Classes (prefer this over mashing className strings):
element.classList.add('active');element.classList.remove('active');element.classList.toggle('active');element.classList.contains('active'); // true/false
Swapping elements
const oldElement = document.querySelector('#old');const newElement = document.createElement('div');newElement.textContent = 'I am new';oldElement.replaceWith(newElement);
Cloning
const original = document.querySelector('.card');// Shallow clone (no children)const clone = original.cloneNode(false);// Deep clone (includes all children)const deepClone = original.cloneNode(true);document.body.appendChild(deepClone);
Interview Tip
Show you know both the modern and legacy APIs — append/remove/replaceWith alongside the older appendChild/removeChild. Reaching for classList rather than hand-editing className is a small signal that you've done this at scale.
Why interviewers ask this
Even in a React-first world, every senior frontend engineer should be able to drop down to raw DOM APIs. This question checks whether you understand what frameworks are doing for you — and whether you could debug or write a 3rd-party integration that needs direct DOM access.