ES6 Shim
The `es6-shim` package provides compatibility shims to enable ECMAScript 6 (Harmony) features in legacy JavaScript environments that lack native support. This includes core language features like `Promise`, `Map`, and `Set`, as well as numerous methods on `String`, `Number`, and `Array` prototypes such as `String.prototype.includes` or `Number.isInteger`. It operates by patching the global scope, making these features available as if they were natively implemented. The current stable version is 0.35.8, which primarily focuses on bug fixes, robustness improvements, and spec compliance. As a polyfill library, its release cadence is driven by bug reports and updates to the ECMAScript specification, rather than frequent feature additions, differentiating it from libraries introducing new paradigms. It aims to make older engines behave as closely as possible to the ES6 standard.
Common errors
-
TypeError: 'Map' is not a constructor (or similar for Set, Promise)
cause The `es6-shim` was not loaded, or `es5-shim` (a prerequisite for some features) was not loaded, or the browser/environment is too old even for shims.fixEnsure `es5-shim` and `es6-shim` are correctly loaded in the specified order before attempting to use ES6 features. Verify that the browser/environment meets the minimum requirements for the shims to function. -
Uncaught (in promise) TypeError: A promise was rejected with a non-error object. (or similar 'uncaught rejection' console warnings)
cause Older Chrome versions (pre-50) or certain environments might incorrectly handle promise rejections, particularly with non-Error objects, leading to console warnings or errors.fixUpdate `es6-shim` to version 0.34.3 or higher, which includes fixes for these issues. Additionally, ensure all promises have a `.catch()` handler to explicitly manage rejections and prevent unhandled promise rejections. -
ReferenceError: Promise is not defined (or Map, Set, etc. is not defined)
cause The `es6-shim` was not loaded at all, or not loaded early enough in the execution flow before these global objects were accessed.fixVerify that the `es6-shim` script is included in your HTML before your application code, or that `require('es6-shim')` is called at the very top of your application's entry point or module where these features are first used. -
SyntaxError: 'const' is a reserved word (or similar for `let`, arrow functions)
cause `es6-shim` polyfills ECMAScript 6 *features* (e.g., `Map`, `Promise`), but it does not transpile ECMAScript 6+ *syntax* (`const`, `let`, arrow functions, classes) for older JavaScript engines.fixFor environments that do not support modern JavaScript syntax, you must use a transpiler like Babel to convert ES6+ syntax to ES5-compatible code. `es6-shim` only provides runtime polyfills for built-in objects and methods.
Warnings
- breaking The `Reflect.enumerate` shim was removed from `es6-shim` in version 0.35.0, aligning with its removal from the official ECMAScript specification.
- gotcha For comprehensive and correct polyfilling, `es5-shim` must always be loaded *before* `es6-shim`. Some ES6 features (like `Map` and `Set`) rely on correct ES5 property descriptor behavior, which `es5-shim` corrects in older environments.
- gotcha The `Map` and `Set` shims, among others, require the target JavaScript environment to have support for ES5 property descriptors. Without this, these shims may not function correctly or at all.
- gotcha The `String.prototype.normalize` shim is incomplete by itself and requires the separate `unorm` package to provide the underlying Unicode normalization algorithm.
- gotcha The `es6-shim` package provides two main files: `es6-shim.js` (for generally safe shims) and `es6-sham.js` (for shims that are less compliant or have potential side effects, such as `Function.prototype.name`).
Install
-
npm install es6-shim -
yarn add es6-shim -
pnpm add es6-shim
Imports
- Global ES6 Polyfills (Browser)
<script src="es6-shim.js"></script> (if not copied to root), or not loading es5-shim first
<script src="node_modules/es6-shim/es6-shim.js"></script>
- Global ES6 Polyfills (Node.js/CommonJS)
import 'es6-shim'; (Incorrect ES module syntax for this package)
require('es6-shim'); - ES6 Sham (Node.js/CommonJS)
require('es6-shim'); (This only loads the main shim, not the 'sham')require('es6-shim/es6-sham');
Quickstart
// In a browser environment, you would include these via script tags in your HTML:
// <script src="node_modules/es5-shim/es5-shim.js"></script>
// <script src="node_modules/es6-shim/es6-shim.js"></script>
// For Node.js or a bundler:
require('es5-shim'); // Recommended for comprehensive polyfilling
require('es6-shim');
// Now, ES6 features are available globally
console.log('--- Map Example ---');
const myMap = new Map();
myMap.set('key1', 'value1');
myMap.set('key2', 'value2');
console.log('Map size:', myMap.size);
console.log('Has key1:', myMap.has('key1'));
console.log('\n--- Promise Example ---');
new Promise((resolve) => {
setTimeout(() => resolve('Promise resolved!'), 100);
}).then(message => {
console.log(message);
}).catch(error => {
console.error('Promise rejected:', error);
});
console.log('\n--- String.prototype.includes Example ---');
const greeting = 'Hello world!';
console.log('"world" included:', greeting.includes('world'));
console.log('"foo" included:', greeting.includes('foo'));
console.log('\n--- Number.isInteger Example ---');
console.log('Is 42 an integer:', Number.isInteger(42));
console.log('Is 3.14 an integer:', Number.isInteger(3.14));