JavaScript Promises support Chrome 32+, Edge 12+, Firefox 29+, Safari 8+, Opera 19+, and Samsung Internet 4+. See full JavaScript Promises browser support.

Prince Dewani
May 1, 2026
JavaScript Promises are a built-in ECMA-262 object that represents the eventual completion or failure of an asynchronous operation. They support Chrome 32+, Edge 12+, Firefox 29+, Safari 8+ on macOS and iOS, Opera 19+, Samsung Internet 4+, and Android Browser 4.4.4+, while Internet Explorer never added native support.
This guide covers what JavaScript Promises are, the browsers that support them, the key features, the difference from async/await, fallback options for older browsers, and the known issues.
A Promise is a JavaScript object defined in the ECMA-262 specification that represents a value that may not be available yet. It moves through three states (pending, fulfilled, rejected) and exposes .then, .catch, and .finally handlers, plus static methods such as Promise.all, Promise.allSettled, Promise.any, and Promise.race.
Native Promise support shipped in every modern engine. Internet Explorer is the only major browser that never added a Promise constructor, and a few static methods (allSettled, any, withResolvers) arrived in later versions.
Chrome supports Promises from Chrome 32 on Windows, macOS, Linux, ChromeOS, and Android. Chrome 4 to 31 did not expose a global Promise constructor, so any reference to Promise threw a ReferenceError. Newer methods follow later: Promise.prototype.finally lands in Chrome 63, Promise.allSettled in Chrome 76, Promise.any in Chrome 85, and Promise.withResolvers in Chrome 119.
Microsoft Edge supports the Promise constructor by default from Edge 12 on Windows. Promise.prototype.finally arrived in Edge 18, and Chromium-based Edge 79+ inherits Chrome's full method set, including Promise.allSettled, Promise.any, and Promise.withResolvers from Edge 119 on Windows, macOS, and Linux.
Firefox supports Promises from Firefox 29 on Windows, macOS, Linux, and Android. Firefox 24 to 28 had Promise behind the dom.promise.enabled flag, and Firefox 2 to 23 had no implementation. Promise.prototype.finally lands in Firefox 58, Promise.allSettled in Firefox 71, Promise.any in Firefox 79, and Promise.withResolvers in Firefox 121.
Safari supports Promises from Safari 8 on macOS Yosemite and from Safari 8 on iOS 8. Safari 3.1 to 7.1 on macOS and Safari 3.2 to 7.1 on iOS did not expose a Promise constructor. Promise.prototype.finally ships in Safari 11.1, Promise.allSettled in Safari 13, Promise.any in Safari 14, and Promise.withResolvers in Safari 17.4.
Opera supports Promises from Opera 19 on Windows, macOS, and Linux through the Chromium 32 base. Opera 9 to 18 on desktop did not implement Promise. Promise.prototype.finally lands in Opera 50, Promise.allSettled in Opera 63, Promise.any in Opera 71, and Promise.withResolvers in Opera 105.
Samsung Internet supports Promises from Samsung Internet 4 on Galaxy phones and tablets running Android. Promise.prototype.finally ships in Samsung Internet 8, Promise.allSettled in Samsung Internet 12, and Promise.any in Samsung Internet 14. Modern Samsung Internet builds align with the underlying Chromium release.
The legacy stock Android Browser supports Promises from Android Browser 4.4.4 on Android KitKat. Android Browser 2.1 to 4.4 did not expose Promise. Modern Android Browser builds inherit Chrome's full Promise method set, so Promise.allSettled, Promise.any, and Promise.withResolvers all run on any current Android phone with Chrome for Android or a Chromium-based shell.
Internet Explorer never added native Promise support. IE 5.5 through IE 11 throw a ReferenceError when any script references the global Promise constructor. Microsoft has retired Internet Explorer, so use Edge, Chrome, or Firefox, or load a Promise polyfill such as es6-promise or core-js before any script that uses Promise.
Note: Promise method support varies across older Safari, mobile browsers, and Internet Explorer. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!
Promises ship a small set of methods and guarantees that replace nested callback code with a flat, composable chain. Each feature below is part of the ECMA-262 specification and runs natively in every modern browser.
Async/await is syntax sugar over Promises, so the two work together rather than competing. The table below shows how the syntax, control flow, error handling, and browser reach differ in practice.
| Dimension | Promises | Async/await |
|---|---|---|
| Syntax style | Chained .then() and .catch() callbacks | Top-to-bottom code with await |
| Return type | Always a Promise (constructed explicitly) | Always a Promise (wrapped automatically) |
| Error handling | .catch() handler at the end of the chain | try/catch around awaits |
| Conditional flow | Nested .then() callbacks or helper functions | Standard if/else and loops with await |
| Concurrency | Promise.all, Promise.race, Promise.allSettled directly | await Promise.all for parallel work |
| Browser support | Chrome 32+, Edge 12+, Firefox 29+, Safari 8+ | Chrome 55+, Edge 15+, Firefox 52+, Safari 11+ |
| Best fit | Library APIs, low-level control, IE-compatible code | Sequential awaits, readable error paths, modern code |
Load a Promise polyfill before any script that calls Promise. The polyfill installs a global Promise constructor that matches the ECMA-262 specification, so the same Promise chain runs on Internet Explorer 11 and on every modern engine.
function loadUser(id) {
return fetch("/api/users/" + id)
.then(function (response) {
if (!response.ok) {
throw new Error("User fetch failed: " + response.status);
}
return response.json();
});
}
loadUser(42)
.then(function (user) {
console.log("User loaded:", user.name);
})
.catch(function (error) {
console.error("Could not load user:", error);
});If the console reports "Promise is not defined", the polyfill import is missing or imported after the first Promise call. Move the polyfill import to the very first line of the entry file and rebuild.
Promises are stable, but a handful of behaviors trip up developers and cause cross-browser bugs. Most of them come from the gap between the spec and how each engine schedules microtasks or surfaces unhandled rejections.
In my experience, the trickiest production failure is a missing .catch on a top-level chain that runs only on a rare error path. The browser quietly fires unhandledrejection in development, but on real devices the same chain crashes a Service Worker install or aborts a Stripe checkout. Always anchor every Promise chain with a final .catch and log to your error reporter.
All JavaScript Promise version numbers and platform notes in this guide come from these primary sources:
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance