Set stores a collection of unique values, automatically discarding duplicates. It replaces manual "check if it's already in the array" logic with a data structure that enforces uniqueness by design.
1The Set Collection | JavaScript Tutorial - In-Depth Guide Part 1
A Set only ever stores unique values — adding a duplicate value is silently a no-op.
const tags = new Set();
tags.add('js');
tags.add('js'); // ignored, already present
tags.size; // 1Guaranteed Uniqueness
2The Set Collection | JavaScript Tutorial - In-Depth Guide Part 2
The famous one-liner '[...new Set(array)]' removes duplicate values from an array, since a Set can be constructed directly from any iterable.
const unique = [...new Set([1, 2, 2, 3, 3, 3])];
// [1, 2, 3]The Dedupe One-Liner
3The Set Collection | JavaScript Tutorial - In-Depth Guide Part 3
Checking membership with Set.prototype.has() is much faster than Array.prototype.includes() for large collections.
const visitedIds = new Set(largeIdArray);
visitedIds.has(someId); // fast, even for huge setsFast Membership Testing
4The Set Collection | JavaScript Tutorial - In-Depth Guide Part 4
Sets don't have native union/intersection/difference methods in most environments yet, but they're trivial to implement with spread and filter.
const union = new Set([...setA, ...setB]);
const intersection = new Set([...setA].filter(x => setB.has(x)));
const difference = new Set([...setA].filter(x => !setB.has(x)));Set Operations
5The Set Collection | JavaScript Tutorial - In-Depth Guide Part 5
Like Map, a Set is directly iterable and maintains insertion order, so you can loop over it with for...of just like an array.
for (const tag of tags) {
console.log(tag);
}Directly Iterable
6Step-by-Step Breakdown
A Set only ever stores unique values — adding a duplicate value is silently a no-op.
Checkpoint: What happens when you .add() a value to a Set that already contains an equal value?
- →Nothing changes, the Set already had it
- →It adds a second, duplicate entry
The famous one-liner '[...new Set(array)]' removes duplicate values from an array, since a Set can be constructed directly from any iterable.
Checking membership with Set.prototype.has() is much faster than Array.prototype.includes() for large collections.
Checkpoint: For checking whether a large collection contains a value, is Set.has() generally faster than Array.includes()?
- →Yes, Set.has() is close to constant time
- →No, they perform identically
Sets don't have native union/intersection/difference methods in most environments yet, but they're trivial to implement with spread and filter.
Like Map, a Set is directly iterable and maintains insertion order, so you can loop over it with for...of just like an array.
Next, we'll explore 'WeakMap'.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Use a Set to Track Which Accessible Announcements Have Already Fired
A Set of already-announced message IDs prevents a live region from repeating the same accessibility announcement multiple times if the same event is processed more than once.
SEO Implications
- 1
No Direct SEO Effect
Set is an in-memory data structure; SEO relevance is limited to general application performance and correctness.
Best Practices
Use a Set for Fast Membership Checks on Large Collections
Repeatedly checking `array.includes(x)` inside a loop is O(n) per check; converting to a Set once up front makes each subsequent check close to O(1).
Use the Spread-Into-Set Idiom for Array Deduplication
It is the shortest, most widely recognized way to deduplicate an array of primitive values, and communicates intent instantly to any experienced JavaScript developer.
Frequent Bugs
Checking membership repeatedly with `array.includes(x)` inside a loop over a large dataset, causing quadratic (O(n²)) overall time complexity.
Build a Set once before the loop and use `.has()` for each check instead, reducing overall complexity to roughly linear.
Expecting `new Set([{a:1}, {a:1}])` to deduplicate two structurally identical but distinct object literals.
Remember Set uses reference equality (like ===) for objects, not deep structural equality — deduplicating structurally-equal-but-distinct objects requires a custom key (like JSON.stringify) or a manual comparison.
Real-World Examples
Deduplicating Tags Across Multiple Articles
A blogging platform needed to compute the unique set of tags used across an entire list of articles, each of which could have overlapping tags.
const allTags = articles.flatMap((a) => a.tags);
const uniqueTags = [...new Set(allTags)];