What is the difference between innerHTML, textContent, and innerText?
Three ways to read or set an element's content, with important differences.
innerHTML — gets/sets HTML markup; parses tags. Powerful but risky with untrusted input (XSS).
textContent — gets/sets plain text including hidden elements; fast and safe.
innerText — like textContent but reflects rendered, visible text and triggers a reflow, so it's slower.
Default to textContent for plain text — safe and fast; use innerHTML only for trusted markup.
// <div id="test">Hello <span style="display:none">Hidden</span> <b>World</b></div>
const el = document.getElementById('test');
console.log(el.textContent); // 'Hello Hidden World' — includes hidden text
console.log(el.innerText); // 'Hello World' — only visible text
console.log(el.innerHTML); // 'Hello <span style="display:none">Hidden</span> <b>World</b>'
// Setting content
el.textContent = '<b>Safe</b>'; // Shows literal '<b>Safe</b>' (no parsing)
el.innerHTML = '<b>Bold</b>'; // Shows bold text (HTML parsed)
el.innerText = '<b>Safe</b>'; // Shows literal '<b>Safe</b>' (no parsing)
// XSS risk with innerHTML
const userInput = '<img src=x onerror=alert("XSS")>';
el.innerHTML = userInput; // DANGEROUS! Script executes
el.textContent = userInput; // SAFE — displayed as texttextContent returns all text including hidden elements. innerText returns only visible text (CSS-aware). innerHTML returns the HTML markup. For setting: textContent and innerText are safe (no HTML parsing), innerHTML parses HTML (XSS risk with user input). textContent is fastest (no reflow).
textContent = fastest + safest (no HTML parsing, includes hidden text). innerText = visible text only (slower, triggers reflow). innerHTML = HTML parsing (XSS risk). For setting user-generated content, ALWAYS use textContent (prevents XSS).