A JavaScript Set is a built-in collection that stores unique values. Add the same value twice and it is only kept once. That makes Sets perfect for removing duplicates, tracking which items have been seen, and checking membership quickly.
Sets arrived in ES2015, and in 2024 they gained a group of long-awaited methods for combining and comparing sets. This guide covers the basics, the newer methods, performance and the gotchas that trip people up.
The short answer
Create a JavaScript Set with new Set(), add values with add(), check them with has() and remove them with delete(). Values are unique and kept in insertion order. To de-duplicate an array, use [...new Set(array)]. Modern browsers also support union(), intersection(), difference() and related methods, which became Baseline in 2024.
Creating a JavaScript Set
You can create an empty set or pass any iterable, such as an array or string:
const tags = new Set();
const colors = new Set(['red', 'green', 'red', 'blue']);
console.log(colors.size); // 3
The duplicate "red" is dropped automatically. Note that the count is the size property, not length.
Core Set methods
| Method or property | What it does | Returns |
|---|---|---|
| add(value) | Adds a value if not already present | The Set (so calls can be chained) |
| has(value) | Checks whether a value exists | true or false |
| delete(value) | Removes a value | true if it was removed |
| clear() | Removes every value | undefined |
| size | Number of values | A number |
| forEach(), values(), keys(), entries() | Iterate over values in insertion order | Iterators or undefined |
Sets are iterable, so you can loop with for...of or spread them into arrays:
for (const color of colors) { console.log(color); }
const list = [...colors];
How Set decides two values are equal
Sets use the SameValueZero comparison. In practice:
- Primitive values compare by value, so 1 and 1 are the same, but 1 and "1" are different.
- NaN is treated as equal to NaN, so a Set only stores one NaN.
- Objects and arrays compare by reference. Two separate objects with identical contents are two different values.
Common uses for a JavaScript Set
Remove duplicates from an array
const unique = [...new Set([3, 1, 3, 2, 1])]; // [3, 1, 2]
Order is preserved based on first appearance. For arrays of objects, de-duplicate by a key instead, for example by tracking seen IDs in a Set.
Track what you have already seen
const seen = new Set();
for (const order of orders) { if (seen.has(order.id)) continue; seen.add(order.id); process(order); }
Fast membership checks
If you check whether a value is in a large list many times, convert the list to a Set first. Engines implement has() with hash-based lookups, which are typically much faster than array.includes() as the collection grows.
Manage UI state
Sets are handy for selected rows in a table, active filters or open accordion panels: add on select, delete on deselect, has() to render.
The newer Set methods: union, intersection and more
For years, developers wrote helper functions to combine sets. Seven methods now do it natively. According to web.dev, they reached Baseline (supported across major browsers) in June 2024, and they are available in Node.js 22 and later.
| Method | Result |
|---|---|
| a.union(b) | A new Set with every value from both |
| a.intersection(b) | Values in both a and b |
| a.difference(b) | Values in a but not in b |
| a.symmetricDifference(b) | Values in either, but not both |
| a.isSubsetOf(b) | true if every value in a is in b |
| a.isSupersetOf(b) | true if a contains every value in b |
| a.isDisjointFrom(b) | true if they share no values |
const frontEnd = new Set(['html', 'css', 'js']);
const fullStack = new Set(['js', 'sql', 'node']);
frontEnd.intersection(fullStack); // Set {'js'}
frontEnd.difference(fullStack); // Set {'html', 'css'}
These methods return new Sets and do not change the originals. Note that difference() is not symmetric: a.difference(b) and b.difference(a) give different results. The argument does not need to be a Set; any "set-like" object with size, has() and keys() works, including a Map. If you support older browsers, check compatibility on MDN's Set reference or use a polyfill.
Set vs Array vs Map vs WeakSet
| Structure | Use it when |
|---|---|
| Array | Order and duplicates matter, or you need index access, sorting and mapping |
| Set | You need unique values and fast membership checks |
| Map | You need key-value pairs with any type of key |
| WeakSet | You need to tag objects without preventing garbage collection |
A real-world example: product filters
Imagine a shop page where customers can tick several filters, such as size, color and brand. Each filter returns the set of matching product IDs. The products to show are the ones that match every active filter, which is exactly an intersection:
const bySize = new Set([101, 102, 105, 108]);
const byColor = new Set([102, 105, 110]);
const byBrand = new Set([100, 102, 105]);
const visible = bySize.intersection(byColor).intersection(byBrand); // Set {102, 105}
Need to show products that match any selected color instead? Use union(). Want to hide items the customer has already dismissed? Use difference() with a set of dismissed IDs. The code reads almost like the business rule, which makes it easier to review and less likely to hide bugs than nested loops and filter() calls.
The same pattern works for permissions (does this user's set of roles include every required role? use isSupersetOf()), tag matching on blogs, and comparing lists of selected dates in booking forms.
Pitfalls to avoid
- No index access: set[0] does not work. Convert to an array first.
- No JSON support: JSON.stringify(new Set([1])) gives "{}". Convert to an array before serializing.
- Objects by reference: new Set([{id: 1}, {id: 1}]) has two items.
- Mutating while iterating: values added during a loop may be visited; avoid changing a set you are looping over.
Small data-structure choices like this add up in larger front-end apps. If your team is scaling a JavaScript codebase, our guide to hiring ReactJS developers covers the skills to look for, and our Node.js development services handle server-side JavaScript. For a wider view of how projects are scoped, see our guide to web development services, or explore Pro Pixel's website design and development work.
Frequently asked questions
Does a JavaScript Set keep insertion order?
Yes. Iteration always follows the order in which values were first added. Deleting and re-adding a value moves it to the end.
How do I convert a Set to an array?
Use the spread syntax, [...mySet], or Array.from(mySet). Array.from also accepts a mapping function as its second argument.
Can a Set contain objects?
Yes, but objects are compared by reference. Two objects with the same properties are stored as separate values.
Is Set faster than an array?
For membership checks on larger collections, usually yes. For small lists or when you need ordering and indexing, arrays are fine and often simpler.
Need clean, maintainable JavaScript behind your website or web app? Our website design and development team builds fast, well-structured front ends and back ends.
More useful paths
Use these paths to continue with the closest practical topic, service, or decision guide.
Pro Pixel Agency
Want this done for you? Try our your website free.
Send a sample, get the finished result back, and only then decide. Clear prices, no commitment.
