Last updated
Features That Cannot Be Polyfilled
- CSS Grid — partial polyfills exist but are incomplete; use flexbox fallbacks instead
- WebAssembly — no JavaScript polyfill possible; use feature detection and fallback logic
- Service Workers — require HTTPS and cannot be polyfilled; use graceful degradation
- WebRTC — too complex to polyfill; use a library like adapter.js for cross-browser normalization
- ES6 Modules — can be transpiled by Babel but not truly polyfilled at runtime
Examples
Example 1: Targeting Browser Support Requirements
Enter your browser support targets and the generator identifies which features need polyfills:
Target Browsers:
last 2 Chrome versions
last 2 Firefox versions
last 2 Safari versions
last 2 Edge versions
IE 11
Features Requiring Polyfills for IE 11:
✗ Promise
✗ fetch
✗ Array.prototype.includes
✗ Array.prototype.flat
✗ Object.assign
✗ Object.entries
✗ String.prototype.padStart
✗ IntersectionObserver
✗ CSS Custom Properties (partial support)
The targeted approach avoids including unnecessary polyfills — only the features your specific browser targets actually need are included.
Example 2: Promise Polyfill
// Feature detection — only loads if Promise is missing:
if (typeof Promise === 'undefined') {
// Promise polyfill implementation
window.Promise = function(executor) {
var callbacks = [];
var state = 'pending';
var value;
function resolve(val) {
if (state !== 'pending') return;
state = 'fulfilled';
value = val;
callbacks.forEach(function(cb) { cb.onFulfilled(val); });
}
function reject(reason) {
if (state !== 'pending') return;
state = 'rejected';
value = reason;
callbacks.forEach(function(cb) { cb.onRejected(reason); });
}
executor(resolve, reject);
return {
then: function(onFulfilled, onRejected) { /* ... */ },
catch: function(onRejected) { /* ... */ }
};
};
}
Example 3: fetch Polyfill
// Feature detection for fetch:
if (!window.fetch) {
window.fetch = function(url, options) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
options = options || {};
xhr.open(options.method || 'GET', url);
// Set headers
if (options.headers) {
Object.keys(options.headers).forEach(function(key) {
xhr.setRequestHeader(key, options.headers[key]);
});
}
xhr.onload = function() {
resolve({
ok: xhr.status >= 200 && xhr.status < 300,
status: xhr.status,
json: function() { return Promise.resolve(JSON.parse(xhr.responseText)); },
text: function() { return Promise.resolve(xhr.responseText); }
});
};
xhr.onerror = function() { reject(new TypeError('Network request failed')); };
xhr.send(options.body || null);
});
};
}