DEV Community

Cover image for HTMLCollection vs NodeList in DOM: A JavaScript Guide
Ritam Saha
Ritam Saha

Posted on

HTMLCollection vs NodeList in DOM: A JavaScript Guide

Introduction

When working with the DOM in JavaScript, you’ll often retrieve groups of elements or nodes. Two of the most common of them you’ll meet are HTMLCollection and NodeList. They look similar at first glance — both are array-like — but they behave differently in important ways.

Neither is a true JavaScript Array, so they don’t have all the usual array methods. Knowing exactly what each one is, how to get it, and where they differ will save you hours of debugging. This short guide covers everything you need.


What is an HTMLCollection?

An HTMLCollection is a live collection that contains only elements nodes (no content nodes, no comments nodes etc.).

It is not an array. You can access items by index or name, but it has no modern array methods like forEach, map, filter, etc.

How to get an HTMLCollection

document.getElementsByTagName('p')
document.getElementsByClassName('highlight')
element.children
document.forms
document.images
// ...and several other legacy properties
Enter fullscreen mode Exit fullscreen mode

HTMLCollection

Key point: Because it is live, the collection updates automatically whenever the DOM changes (elements added, removed, or moved).


What is a NodeList?

A NodeList is a collection that can contain any type of node (elements, text nodes, comments, etc.). Some NodeLists are static and some are live.

It is also not an array, but modern NodeLists are friendlier: they support forEach(), for...of, entries(), keys(), and values().

How to get a NodeList

document.querySelectorAll('p')           // ← static
element.childNodes                       // ← live
document.getElementsByName('username')   // live in some cases
Enter fullscreen mode Exit fullscreen mode

NodeList

Key point: Most people use querySelectorAll(), which returns a static snapshot. Other NodeLists (like childNodes) are live.


Key Differences: HTMLCollection vs NodeList

forEach() Support

NodeList has forEach().
HTMLCollection does not.

If you try:

const collection = document.getElementsByTagName('li');
collection.forEach(...) // → TypeError: collection.forEach is not a function
Enter fullscreen mode Exit fullscreen mode

forEach() support

Fix: Convert to a real array first:

Array.from(collection).forEach(...)
Enter fullscreen mode Exit fullscreen mode

Live vs Static Behavior

HTMLCollection is always live.
NodeList from querySelectorAll() is static.

Here’s a complete demo you can use to see the difference:

<div id="container">
      <p>Paragraph 1</p>
</div>

<script>
      // HTMLCollection – LIVE
      const htmlColl = document.getElementsByTagName("p");
      console.log("Initial HTMLCollection length:",htmlColl.length); // 1

      // Add a new paragraph
      const newP = document.createElement("p");
      newP.textContent = "Paragraph 2";
      document.getElementById("container").appendChild(newP);

      console.log("After DOM change – HTMLCollection length:",htmlColl.length); // 2
</script>
Enter fullscreen mode Exit fullscreen mode

Live Update

<div id="container">
      <p>Paragraph 1</p>
</div>

<script>
      // NodeList from querySelectorAll – STATIC
      const nodeList = document.querySelectorAll("p");
      console.log("Initial NodeList length:", nodeList.length); // 1

      // Add a new paragraph
      const newP = document.createElement("p");
      newP.textContent = "Paragraph 2";
      document.getElementById("container").appendChild(newP);

      console.log("After DOM change – NodeList length:",nodeList.length); // Still 1; no update
</script>
Enter fullscreen mode Exit fullscreen mode

Static

Content:

HTMLCollection = only elements nodes;
NodeList = all nodes

Best practice: When you need array methods or don’t want surprises, convert both with Array.from()


Conclusion

HTMLCollection and NodeList are both useful, but they are not interchangeable.

Use querySelectorAll() + NodeList when you want modern iteration as well as a stable snapshot.

Use getElementsByTagName/getElementsByClassName + HTMLCollection when you need live updates.

And remember the golden rule: when in doubt, turn it into a real array with Array.from().

Master these two and your DOM code becomes cleaner, faster, and far less error-prone. Happy coding!

Top comments (0)