Modern JavaScript built-ins you can use in 2026: a browser support checklist
A practical October 2026 checklist of modern JavaScript built-ins, from Object.groupBy and Set methods to iterator helpers, RegExp.escape and Base64 on Uint8Array, with first supporting browser versions and what still needs a fallback.
Updated 7 min read

In this article
Many front-end projects still ship helper libraries and polyfills for things the browser now does natively: grouping arrays, set operations, Base64 encoding, escaping strings for regular expressions. Each extra dependency adds bytes to download, code to audit and versions to update. At the same time, a few eye-catching new features are not ready everywhere, and using them without checking breaks the site for part of your audience.
This guide is a practical checklist for October 2026. It lists modern JavaScript built-ins, the first Chrome, Firefox and Safari versions that support them according to MDN's browser compatibility data (version 8.1.4, published 1 October 2026), and a short example of each. Use it to decide what you can delete from your bundle, and what still needs a fallback.
The versions below refer to desktop browsers; Safari on iOS has the same version numbers for every feature listed here. Edge uses the same version numbers as Chrome.
How to read "supported" in 2026
The web.dev Baseline project gives a shared vocabulary. A feature is Baseline newly available when it is supported by all the core browsers: Chrome (desktop and Android), Edge, Firefox (desktop and Android) and Safari (macOS and iOS). It becomes Baseline widely available 30 months after that date, when "the feature can be used by most sites without worrying about support".
Your own analytics matter more than any general rule. A business tool used on managed office laptops can adopt newer features faster than a consumer site with many older phones. A simple policy is: use widely available features freely, use newly available features when your analytics show the older versions are rare, and feature-detect everything else.

Safe to use: features from the last few years
| Feature | Chrome | Firefox | Safari | Replaces |
|---|---|---|---|---|
Array.prototype.at(), Object.hasOwn() | 92 / 93 | 90 / 92 | 15.4 | arr[arr.length - 1], hasOwnProperty.call |
Error cause option | 93 | 91 | 15 | Custom error wrapping |
findLast(), findLastIndex() | 97 | 104 | 15.4 | Reverse-and-find loops |
toSorted(), toReversed(), with() | 110 | 115 | 16 | Copy-then-mutate patterns |
Array.fromAsync() | 121 | 115 | 16.4 | Manual for await collection |
Object.groupBy(), Map.groupBy() | 117 | 119 | 17.4 | Lodash groupBy |
Promise.withResolvers() | 119 | 121 | 17.4 | Deferred-promise helpers |
Set methods (union, intersection, difference, ...) | 122 | 127 | 17 | Set utility libraries |
Non-mutating array methods
const prices = [499, 99, 1299];
const sorted = prices.toSorted((a, b) => a - b); // [99, 499, 1299]
const updated = prices.with(1, 149); // [499, 149, 1299]
console.log(prices); // unchanged: [499, 99, 1299]These matter in React and other state-driven UIs, where mutating an array in place causes missed re-renders.
Grouping
const orders = [
{ id: 1, status: 'paid' },
{ id: 2, status: 'pending' },
{ id: 3, status: 'paid' },
];
const byStatus = Object.groupBy(orders, (o) => o.status);
// { paid: [{id: 1,…}, {id: 3,…}], pending: [{id: 2,…}] }Object.groupBy() returns an object with a null prototype, so call Object.keys() on it rather than methods such as hasOwnProperty. Use Map.groupBy() when keys are not strings.
Set operations
const required = new Set(['read', 'write']);
const granted = new Set(['read', 'comment']);
required.difference(granted); // Set {'write'}: what is missing
required.isSubsetOf(granted); // false
required.union(granted); // Set {'read', 'write', 'comment'}The full set is union, intersection, difference, symmetricDifference, isSubsetOf, isSupersetOf and isDisjointFrom. Remember that browser-side permission checks are for display only; the server must still enforce access.
Newer, now in all three engines
| Feature | Chrome | Firefox | Safari |
|---|---|---|---|
Iterator helpers (Iterator.from, map, filter, take, drop, toArray, ...) | 122 | 131 | 18.4 |
Promise.try() | 128 | 134 | 18.2 |
Uint8Array Base64 and hex (toBase64, fromBase64, toHex, fromHex) | 140 | 133 | 18.2 |
RegExp.escape() | 136 | 134 | 18.2 |
Float16Array, Math.f16round() | 135 | 129 | 18.2 |
Error.isError() | 134 | 138 | 18.4 |
JSON.rawJSON(), JSON.isRawJSON() | 114 | 135 | 18.4 |
Regular expression modifiers, e.g. (?i:...) | 125 | 132 | 26 |
Map and WeakMap getOrInsert(), getOrInsertComputed() | 145 | 144 | 26.2 |
Math.sumPrecise() | 147 | 137 | 26.2 |
Iterator.concat() | 146 | 147 | 26.4 |
Features in the upper rows have been in every engine for longer. The lower rows, which need Safari 26.x or Chrome 145 and later, are recent: check your traffic before relying on them without a fallback.
Iterator helpers: lazy pipelines without arrays
function* naturals() {
let n = 1;
while (true) yield n++;
}
const firstFiveEvenSquares = naturals()
.filter((n) => n % 2 === 0)
.map((n) => n * n)
.take(5)
.toArray(); // [4, 16, 36, 64, 100]Unlike array methods, iterator helpers process one value at a time, so the infinite generator above is safe. They also work on the iterators returned by map.entries(), set.values() and DOM collections' iterators, avoiding temporary arrays.
Base64 without btoa() surprises
const bytes = new TextEncoder().encode('नमस्ते'); // UTF-8 bytes
const encoded = bytes.toBase64(); // works for any bytes
const decoded = new TextDecoder().decode(Uint8Array.fromBase64(encoded));
const hex = new Uint8Array([255, 16]).toHex(); // "ff10"The old btoa() throws on characters outside Latin-1, which regularly breaks Hindi, Tamil or emoji text. The Uint8Array methods operate on bytes, so encode text with TextEncoder first.
Escaping user input in regular expressions
const term = 'C++ (beta)';
const re = new RegExp(RegExp.escape(term), 'i');
re.test('Learning c++ (BETA) today'); // trueThis replaces the hand-written escaping helpers found in many search features, which often miss a character.
Upserts on Map
const counts = new Map();
for (const word of ['js', 'ts', 'js']) {
counts.set(word, counts.getOrInsert(word, 0) + 1);
}
// Map {'js' => 2, 'ts' => 1}
const cache = new Map();
const user = cache.getOrInsertComputed(42, (id) => ({ id, loadedAt: Date.now() }));
Safer error handling with Promise.try() and Error.isError()
function loadSettings(source) {
// Wraps both synchronous throws and async rejections in one promise
return Promise.try(() => source.read());
}
loadSettings(storage).catch((err) => {
// true for real Error objects, including ones from other realms such as iframes
if (Error.isError(err)) {
reportError(err);
} else {
reportError(new Error('Non-error thrown', { cause: err }));
}
});Promise.try() removes the classic bug where a function that throws synchronously escapes a .catch() handler. Error.isError() is more reliable than instanceof Error when errors cross frames or workers. Together with the cause option they make error reporting more consistent.
Not ready everywhere: feature-detect or wait
| Feature | Chrome | Firefox | Safari |
|---|---|---|---|
Temporal | 144 | 139 | Technology Preview only |
using / await using, DisposableStack | 134 | 141 | Technology Preview only |
Iterator.zip() | 153 | 148 | Technology Preview only |
Iterator chunks() | No | 154 | Technology Preview only (marked experimental) |
For APIs (functions and objects), feature detection is simple:
if (typeof globalThis.Temporal === 'undefined') {
await import('temporal-polyfill/global');
}
const zip = typeof Iterator.zip === 'function'
? Iterator.zip
: null; // fall back to your own helperSyntax is different. A using declaration is a parse error in a browser that does not understand it, so the whole script fails, not just one line. Either compile it away with your build tool or wait until all your target browsers support it. Check your transpiler's documentation for which proposals it can transform.
A checklist for cleaning up your bundle
- Export a browser and version report from your analytics for the last 90 days, including iOS versions.
- Set your build target (for example a Browserslist query or your bundler's
targetoption) to match that audience, and keep it in version control. - Search your dependencies and code for helpers the platform now covers:
groupBy, deep set utilities, Base64 helpers, regex-escape functions, "deferred" promise helpers,last()helpers. - Replace them one module at a time and remove the dependency when the last import is gone.
- Check that your polyfill service or
core-jsconfiguration only includes what your targets need. - For anything in the "not ready" table, add feature detection and a tested fallback, or hold it back.
- Set a review date. Browser support changes every few weeks; repeat the audit each quarter.
- Run your test suite in at least one Chromium, one Firefox and one WebKit browser before each release, so a missing method fails in CI rather than for a customer.
TypeScript note
Type definitions lag behind or lead browsers. TypeScript 6.0 added an es2025 target and library, including types for RegExp.escape, Temporal and the Map upsert methods. If the compiler says a method does not exist, check your lib setting before adding a polyfill: the problem may be types, not runtime support.
Summary
A large set of once-missing built-ins now works in Chrome, Firefox and Safari: immutable array methods, grouping, Set operations, iterator helpers, Promise.try(), byte-level Base64 and RegExp.escape(). They let you remove dependencies and write clearer code. Temporal, explicit resource management with using and Iterator.zip() are still missing from Safari, so treat them as progressive enhancements or wait. Check MDN's compatibility tables and your own analytics before each decision.
Frequently asked questions
Where do the version numbers in this checklist come from?
From MDN's browser compatibility data, version 8.1.4, published on 1 October 2026. Safari on iOS has the same version numbers as desktop Safari for every feature listed.
What is the difference between Baseline newly and widely available?
Newly available means all core browsers (Chrome, Edge, Firefox and Safari, desktop and mobile) support the feature. Widely available means 30 months have passed since that point.
Can I polyfill the using declaration?
No.
usingis new syntax, and browsers that do not understand it fail to parse the whole script. You need a build step that transforms it, or you must wait for support in all target browsers.Why does TypeScript say a supported method does not exist?
Usually your
libsetting is older than the feature. TypeScript 6.0 added anes2025library with types for methods such asRegExp.escape.
Your next customer could start right here.
Introduce your tool, product or business to readers exploring technology.
Explore placements and request a private quote
Sources
- MDN browser-compat-data 8.1.4 (data.json) — MDN Web Docs, 2026-10-01
- Baseline — web.dev (Google)
- Temporal — MDN Web Docs
- Announcing TypeScript 6.0 — Microsoft, 2026-03-23
- temporal-polyfill — FullCalendar
Written with substantial AI assistance. Facts checked against cited sources. Editorial policy.
Comments
No comments yet. Be the first to join the conversation.
Leave a comment
Every comment is read by a moderator before it appears. Your email address is never published; it is used only to contact you about this comment.
More from Cloudsoft Zone

TutorialJavaScript
JavaScript using declarations: automatic cleanup without finally
Learn JavaScript's using and await using declarations, Symbol.dispose and DisposableStack, with tested browser recipes and October 2026 support data.
By Cloudsoft Zone

Architecture guideJavaScript
Ship JavaScript without a bundler: import maps and JSON modules
How to structure a front end as native ES modules: import maps for bare imports, JSON modules, modulepreload against waterfalls, and cache-busting.
By Cloudsoft Zone

ComparisonJavaScript
structuredClone vs JSON vs spread: deep copy JavaScript safely
Spread is shallow, JSON loses dates, Maps, Sets and undefined, and structuredClone keeps them. A tested comparison of JavaScript copy methods and their limits.
By Cloudsoft Zone
