JavaScript Set Methods: Native Set Theory, Finally

JavaScript Set Methods: Native Set Theory, Finally

Seven new methods landed on JavaScript's Set: union, intersection, difference, and more. Baseline since 2024. A practical guide with real-world examples.

Martin Ferret

Martin Ferret

July 7, 2026

JavaScript's Set has existed since ES2015, but for almost a decade it was missing the operations every set theory textbook starts with: union, intersection, difference. You had to roll them yourself with filter and spread operators, or import Lodash. Since 2024, that gap is closed. Seven new methods landed on Set.prototype, and they are now part of Baseline.

The Problem They Solve

Before these methods, computing the intersection of two arrays meant something like this:

      const a = [1, 2, 3, 4];
const b = [3, 4, 5, 6];

const intersection = a.filter((x) => b.includes(x));
// [3, 4]

    

It works, but Array.prototype.includes is O(n), so the whole thing is O(n²). Switching to Set for the lookup helps performance, but you still write the loop yourself. And union, symmetric difference, and subset checks each need their own helper. Most codebases ended up with a setUtils.ts file, or pulled in Lodash for _.intersection, _.union, and _.difference.

The Seven New Methods

The proposal adds seven methods to Set.prototype. Four return a new Set, three return a boolean.

union(other)

Returns a new set with every element from either set:

      const a = new Set([1, 2, 3]);
const b = new Set([3, 4, 5]);

a.union(b); // Set(5) { 1, 2, 3, 4, 5 }

    

intersection(other)

Returns a new set with only the elements present in both:

      const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);

a.intersection(b); // Set(2) { 3, 4 }

    

difference(other)

Returns a new set with elements in a but not in b:

      const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);

a.difference(b); // Set(2) { 1, 2 }

    

symmetricDifference(other)

Returns elements that are in one set or the other, but not both:

      const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);

a.symmetricDifference(b); // Set(4) { 1, 2, 5, 6 }

    

isSubsetOf, isSupersetOf, isDisjointFrom

Three boolean predicates for relationships between sets:

      const all = new Set([1, 2, 3, 4, 5]);
const some = new Set([2, 3]);
const other = new Set([6, 7]);

some.isSubsetOf(all);      // true
all.isSupersetOf(some);    // true
all.isDisjointFrom(other); // true

    

A Useful Detail: set-like Objects

All seven methods accept any set-like object as the argument, not just Set instances. A set-like object is anything that exposes a numeric size property, a has(value) method, and a keys() method returning an iterator. This means custom collections can interoperate with native Set operations without conversion.

The constraint applies only to the argument. The receiver, meaning the set you call the method on, must still be an actual Set instance, because the methods reach directly into its internal storage for performance.

Practical Examples

Checking permissions. Set operations express access control naturally:

      function hasRequiredPermissions(userPerms, requiredPerms) {
  return new Set(requiredPerms).isSubsetOf(new Set(userPerms));
}

hasRequiredPermissions(
  ['read', 'write', 'delete'],
  ['read', 'write']
); // true

    

Tag filtering. Find posts that match any selected tag:

      const selectedTags = new Set(['javascript', 'typescript']);
const postTags = new Set(['javascript', 'react', 'node']);

selectedTags.intersection(postTags).size > 0; // true

    

Diffing two states. Useful in reducers, sync logic, or migration scripts:

      const oldIds = new Set([1, 2, 3, 4]);
const newIds = new Set([3, 4, 5, 6]);

const added = newIds.difference(oldIds);   // Set(2) { 5, 6 }
const removed = oldIds.difference(newIds); // Set(2) { 1, 2 }
const kept = oldIds.intersection(newIds);  // Set(2) { 3, 4 }

    

The intent is immediate. No filter, no includes, no helper imports.

What to Watch Out For

Order. The returned set preserves a defined order. For union, elements from the receiver come first, then elements from the argument that were not already present. For intersection and difference, the order follows the receiver. This is specified, not implementation-defined.

Receiver constraint. Calling set.union(somethingNotSetLike) throws a TypeError. The argument must be either a real Set or a fully set-like object.

No mutation. All four returning methods produce a new Set. The original is untouched. This is consistent with map and filter on arrays, and it means you can chain operations safely.

Where It Runs Today

The Set methods reached Baseline "newly available" in June 2024, meaning all four major browser engines support them.

Browsers. Chrome and Edge from version 122 (February 2024). Safari from 17 (September 2023). Firefox from 127 (June 2024). With Firefox 127, every major browser engine shipped the feature, and polyfills became unnecessary in browser code.

Runtimes. Node.js supports the methods natively from version 22 (April 2024), which embeds V8 12.4. Deno and Bun support them in current versions.

Tooling. TypeScript ships the type definitions in 5.5 and above. For older runtimes, dedicated polyfills exist on npm (set.prototype.union, set.prototype.intersection, and so on), and core-js covers the whole family.

In practice. For a modern Angular, NestJS, React, or Vue project bundled with Vite or Webpack, the Set methods can be used today without precaution. The one situation to watch: applications targeting older browsers (Safari below 17, Firefox below 127) or older Node LTS (20 and below) still need a polyfill.

What to Take Away

The Set methods do not let you do anything you could not do before. What they change is how much code you need to express it. A subset check becomes one method call. A diff between two states becomes three readable lines. The intent is finally in the code instead of buried inside a reduce or a chain of filter calls.

For developers handling permission checks, tag filters, ID diffing, or any domain where collections compare to one another, replacing manual helpers with the native methods is a clean win. Less code, faster execution, no dependency.

More certificates.dev articles

Get the latest news and updates on developer certifications. Content is updated regularly, so please make sure to bookmark this page or sign up to get the latest content directly in your inbox.