JavaScript is a living language. Every year, the TC39 committee finalizes a new batch of features that expand what developers can express without transpilers, polyfills, or external libraries. ES2024 brings array grouping, deferred promises, Unicode string validation, and powerful RegExp set operations. ES2025, currently in draft, promises iterator helpers for lazy evaluation, mathematical set operations on Set objects, and convenience utilities like Promise.try and RegExp.escape.
Yet many production codebases still use lodash for grouping, hand-rolled deferred promise patterns, and verbose regex escapes. Developers either do not know these features exist or are unsure which engines support them. Our free interactive JavaScript ES2024+ Features Cheat Sheet maps forty-five modern APIs across ten categories, from finalized ES2024 capabilities to upcoming ES2025 additions. Each entry includes a concise explanation, a copyable code example, and status badges that distinguish finalized features from draft proposals. The Crystal Codex aesthetic — deep midnight navy, holographic constellation effects, and prismatic glass cards — turns language exploration into a journey through the future of JavaScript. Everything runs in your browser with no server interaction, no signup, and no data collection.
Why Modern JavaScript Features Deserve a Dedicated Reference
The ECMAScript specification is dense. A single feature like the RegExp v flag spans Unicode property escapes, set notation, string properties, and interaction with the u flag. Object.groupBy seems simple until you consider how it differs from Map.groupBy, what happens with symbol keys, and how it handles sparse arrays. Promise.withResolvers is straightforward in isolation but unlocks patterns — locks, semaphores, cancellable promises — that previously required boilerplate.
A unified cheat sheet provides three benefits. First, it surfaces features that solve common problems without dependencies. Array grouping eliminates the need for lodash.groupby in most codebases. Iterator helpers replace many hand-rolled generator functions. Set operations remove the need for external set libraries. Second, it clarifies the boundary between finalized features you can use today and draft features that require feature flags or transpilation. Third, it provides copyable examples that you can paste directly into your codebase, adapting them to your naming conventions and types.
The cheat sheet covers both ES2024 finalized features and ES2025 draft features. ES2024 features are supported in modern browsers and Node.js 22+ without flags. ES2025 features are available behind flags in some engines and are expected to ship unflagged in late 2025. We label every entry clearly so you know what you can deploy today.
Array Copying Methods — toSorted, toReversed, toSpliced, with
Before ES2023, sorting or reversing an array mutated the original. This forced developers to create defensive copies with spread syntax or slice before every mutation. The copying methods return a new array while leaving the original untouched, aligning array operations with functional programming principles.
toSorted — Non-Destructive Sort
Array.prototype.toSorted behaves like sort but returns a new array. The original remains unchanged. This is essential in reactive frameworks where mutating state directly causes bugs or violates immutability constraints.
{`const scores = [42, 100, 15, 8];
const ranked = scores.toSorted((a, b) => b - a);
console.log(ranked); // [100, 42, 15, 8]
console.log(scores); // [42, 100, 15, 8] — unchanged`} toReversed — Non-Destructive Reverse
toReversed returns a new array with elements in opposite order. Use it when you need to display data in descending order without mutating the source.
{`const timeline = ['post1', 'post2', 'post3'];
const feed = timeline.toReversed();
console.log(feed); // ['post3', 'post2', 'post1']
console.log(timeline); // ['post1', 'post2', 'post3']`} toSpliced — Non-Destructive Splice
toSpliced is the copying version of splice. It removes elements and inserts replacements, returning a new array while preserving the original.
{`const items = ['a', 'b', 'c', 'd', 'e'];
const edited = items.toSpliced(1, 2, 'x', 'y');
console.log(edited); // ['a', 'x', 'y', 'd', 'e']
console.log(items); // ['a', 'b', 'c', 'd', 'e']`} with — Replace at Index
The with method replaces a single element at a given index. It is the array equivalent of updating a tuple by index in immutable languages.
{`const colors = ['red', 'green', 'blue'];
const updated = colors.with(1, 'yellow');
console.log(updated); // ['red', 'yellow', 'blue']
console.log(colors); // ['red', 'green', 'blue']`} Array Searching — findLast and findLastIndex
Before ES2023, finding the last matching element required reversing the array or manually iterating from the end. findLast and findLastIndex search from the last element toward the first, returning the match or its index directly.
{`const logs = [
{ level: 'info', msg: 'start' },
{ level: 'warn', msg: 'slow' },
{ level: 'error', msg: 'crash' },
{ level: 'info', msg: 'retry' },
];
const lastError = logs.findLast(l => l.level === 'error');
console.log(lastError.msg); // 'crash'
const lastErrorIndex = logs.findLastIndex(l => l.level === 'error');
console.log(lastErrorIndex); // 2`} Array Grouping — Object.groupBy and Map.groupBy
Grouping is one of the most common data transformations. Before ES2024, developers used lodash.groupby, manual reduce loops, or Map-based accumulators. The new static methods provide a native, optimized, and readable solution.
Object.groupBy — String-Keyed Groups
Object.groupBy groups array elements into a plain object. The callback returns a string that becomes the group key. This is ideal when your grouping key is a category name, status label, or date string.
{`const orders = [
{ status: 'pending', total: 120 },
{ status: 'shipped', total: 85 },
{ status: 'pending', total: 45 },
];
const byStatus = Object.groupBy(orders, o => o.status);
// {
// pending: [{ status: 'pending', total: 120 }, { status: 'pending', total: 45 }],
// shipped: [{ status: 'shipped', total: 85 }]
// }`} Map.groupBy — Any-Keyed Groups
Map.groupBy groups elements into a Map, allowing any value type as a key. This is essential when your grouping key is an object, a tuple, or a Symbol that cannot be coerced to a string.
{`const users = [
{ name: 'Alice', tags: new Set(['admin', 'dev']) },
{ name: 'Bob', tags: new Set(['dev']) },
];
// Group by a specific tag object
const adminTag = { role: 'admin' };
const byAdmin = Map.groupBy(users, u =>
u.tags.has('admin') ? adminTag : 'other'
);
console.log(byAdmin.get(adminTag)); // [{ name: 'Alice', ... }]`} Promise Utilities — Promise.withResolvers
Deferred promise patterns appear in locks, queues, cancellable operations, and test mocks. Before Promise.withResolvers, developers created a let variable outside the Promise constructor and assigned resolve and reject inside the executor. This was verbose and error-prone.
Basic Deferred Pattern
{`const { promise, resolve, reject } = Promise.withResolvers();
setTimeout(() => resolve('data loaded'), 1000);
const result = await promise;
console.log(result); // 'data loaded' after 1s`} Mutex Lock Implementation
{`class Mutex {
#locked = false;
#queue = [];
async acquire() {
if (!this.#locked) {
this.#locked = true;
return;
}
const deferred = Promise.withResolvers();
this.#queue.push(deferred);
await deferred.promise;
}
release() {
const next = this.#queue.shift();
if (next) next.resolve();
else this.#locked = false;
}
}`} String Methods — isWellFormed and toWellFormed
JavaScript strings are sequences of UTF-16 code units. A "lone surrogate" is a code unit from the surrogate range (0xD800–0xDFFF) that does not form a valid surrogate pair. Lone surrogates break encoding operations, database inserts, and JSON serialization. The new methods detect and repair them.
isWellFormed — Validation
{`const valid = 'hello';
const invalid = '\uD800'; // lone surrogate
console.log(valid.isWellFormed()); // true
console.log(invalid.isWellFormed()); // false`} toWellFormed — Repair
{`const dirty = '\uD800abc';
const clean = dirty.toWellFormed();
console.log(clean); // '�abc' — lone surrogate replaced with replacement character`} RegExp Features — The v Flag
The RegExp v flag, introduced in ES2024, is an evolution of the u flag. It enables Unicode sets mode, which supports set operations inside character classes and multi-character property escapes.
Set Operations in Character Classes
With the v flag, you can use intersection (&&), union (implicit), and difference (--) inside character classes. This makes complex Unicode matching patterns readable and maintainable.
{`// Intersection: ASCII letters only
const asciiLetters = /^[\p{ASCII}&&\p{Letter}]+$/v;
console.log(asciiLetters.test('abc')); // true
console.log(asciiLetters.test('123')); // false
// Difference: decimal numbers except ASCII digits
const nonAsciiDigits = /[\p{Decimal_Number}--[0-9]]/v;
console.log(nonAsciiDigits.test('٠')); // true (Arabic-Indic digit)`} Multi-Character Properties
The v flag allows multi-character Unicode properties like Emoji inside character classes, which was impossible with the u flag.
{`const emojiOnly = /^[\p{Emoji}]+$/v;
console.log(emojiOnly.test('\u{1F600}')); // true
console.log(emojiOnly.test('abc')); // false`} Atomics — waitAsync
SharedArrayBuffer enables multiple threads to share memory. Atomics provides lock-free synchronization primitives. Atomics.wait blocks the thread synchronously, which is only usable in Worker threads. Atomics.waitAsync, added in ES2024, returns a promise so the main thread can wait without blocking.
{`const sab = new SharedArrayBuffer(4);
const int32 = new Int32Array(sab);
// Start an async wait
const result = Atomics.waitAsync(int32, 0, 0);
// In a worker or later in the event loop:
Atomics.notify(int32, 0, 1);
// Await the result without blocking the main thread
const status = await result.value;
console.log(status); // 'ok'`} Iterator Helpers — Lazy Evaluation for ES2025
Array methods like map and filter create intermediate arrays. For large datasets or infinite sequences, this is wasteful. Iterator helpers operate lazily: values are computed only when consumed. They are expected in ES2025 and are available in modern engines.
map, filter, and take
{`const iter = [1, 2, 3, 4, 5].values();
const pipeline = iter
.map(x => x * 2)
.filter(x => x > 4)
.take(2);
console.log([...pipeline]); // [6, 8]
// Only 4 values were consumed from the source`} drop and flatMap
{`const iter = [1, 2, 3, 4, 5].values();
const rest = iter.drop(2).flatMap(x => [x, x * 10]);
console.log([...rest]); // [3, 30, 4, 40, 5, 50]`} reduce, toArray, and Predicates
{`const iter = [1, 2, 3, 4].values();
const sum = iter.reduce((a, b) => a + b, 0);
console.log(sum); // 10
const someEven = [1, 3, 5, 6].values().some(x => x % 2 === 0);
console.log(someEven); // true
const allPositive = [1, 2, 3].values().every(x => x > 0);
console.log(allPositive); // true`} Set Operations — Mathematical Sets in ES2025
JavaScript Set objects previously lacked mathematical operations. Developers used libraries or manual iteration to compute unions, intersections, and differences. ES2025 adds seven methods that treat sets as mathematical sets.
{`const evens = new Set([2, 4, 6, 8]);
const primes = new Set([2, 3, 5, 7]);
console.log([...evens.union(primes)]); // [2, 4, 6, 8, 3, 5, 7]
console.log([...evens.intersection(primes)]); // [2]
console.log([...evens.difference(primes)]); // [4, 6, 8]
console.log([...evens.symmetricDifference(primes)]); // [4, 6, 8, 3, 5, 7]
console.log(evens.isSubsetOf(new Set([2, 4, 6, 8, 10]))); // true
console.log(evens.isSupersetOf(new Set([2, 4]))); // true
console.log(evens.isDisjointFrom(new Set([1, 3, 5]))); // true`} New Globals — Promise.try, RegExp.escape, and ArrayBuffer.transfer
ES2025 introduces convenience utilities that reduce boilerplate in common patterns.
Promise.try
Promise.try wraps a synchronous function call in a promise, catching thrown errors and rejecting the promise. This eliminates the try/catch boilerplate when calling sync functions that might throw.
{`Promise.try(() => {
const data = JSON.parse(maybeInvalidJson);
return data;
}).catch(err => {
console.log('Parse failed:', err.message);
});`} RegExp.escape
RegExp.escape takes a string and escapes all special regular expression characters. This is essential when building dynamic regex patterns from user input.
{`const userInput = 'Hello. How are you?';
const escaped = RegExp.escape(userInput);
// 'Hello\\. How are you\\?'
const re = new RegExp(escaped);
console.log(re.test(userInput)); // true`} ArrayBuffer.transfer
ArrayBuffer.transfer moves the contents of an ArrayBuffer to a new one and detaches the original. This is useful when passing buffers between threads or resizing buffers without copying.
{`const ab1 = new ArrayBuffer(8);
const view1 = new Uint8Array(ab1);
view1[0] = 42;
const ab2 = ab1.transfer();
console.log(ab1.byteLength); // 0 (detached)
console.log(ab2.byteLength); // 8
const view2 = new Uint8Array(ab2);
console.log(view2[0]); // 42`} How to Use This Cheat Sheet Effectively
The interactive JavaScript ES2024+ Features Cheat Sheet is organized into ten categories that map to real development workflows. Use the search bar to find a specific API by name or description. Use the category tabs to browse related features together. Every code example includes a one-click copy button so you can paste the snippet directly into your editor.
Start with the Array Copying and Array Grouping categories if you are refactoring data transformation code. These features replace common lodash and utility library patterns with native, optimized implementations. Move to Promise Utilities when you build async coordination primitives like locks, queues, or deferred tasks. The RegExp Features and String Methods categories are essential for internationalized applications that handle Unicode text and complex matching patterns.
The Iterator Helpers and Set Operations categories are where JavaScript catches up to languages like Python and Rust in collection ergonomics. If you process large datasets, streams, or generator pipelines, iterator helpers will become your daily tools. The Atomics and New Globals sections are worth reviewing before you optimize or build multi-threaded applications.
Related Resources
Modern JavaScript features do not exist in isolation. They combine with existing language primitives and tooling to form a complete development stack. If you are working with arrays and strings, our JavaScript Array Methods Cheat Sheet and JavaScript String Methods Cheat Sheet provide complementary references for the foundational APIs. For error handling patterns, the JavaScript Error Handling Patterns Cheat Sheet covers try/catch, promise rejection handling, and structured error patterns. For TypeScript projects, the TypeScript Utility Types Cheat Sheet and TypeScript Types Cheat Sheet cover the type system.
Our interactive JavaScript ES2024+ Features Cheat Sheet is the fastest way to look up any modern API, copy a working example, and understand when to apply it. It is free, runs entirely in your browser, and requires no registration.