ECMAScript 6 (Harmony) compatibility shims for legacy JavaScript engines
Pull request Compare This branch is 1 commit behind paulmillr:master.
Failed to load latest commit information.
node_modules [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `es5-shim`, `eva… Apr 30, 2018
test-sham [Dev Deps] update `es5-shim`, `eslint`, `@ljharb/eslint-config`, `jsc… Nov 14, 2016
test [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `es5-shim`, `eva… Apr 30, 2018
.eslintignore [Tests] add `npm run eslint` Nov 1, 2015
.eslintrc [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `es5-shim`, `eva… Apr 30, 2018
.gitignore Only apps should have lockfiles Jun 14, 2017
.jscs.json [Tests] up to `node` `v10.0`, `v9.11`, `v8.11`, `v6.14`, `v4.9`; use … Apr 30, 2018
.jshintrc Promise: Improve performance of TypeIsObject abstract operation. Dec 15, 2015
.npmignore Don’t npmignore tests. Jan 4, 2016
.npmrc Only apps should have lockfiles Jun 14, 2017
.travis.yml [Tests] up to `node` `v10.0`, `v9.11`, `v8.11`, `v6.14`, `v4.9`; use … Apr 30, 2018 v0.35.3 Jan 24, 2017
Gruntfile.js [Tests] add `npm run eslint` Nov 1, 2015
LICENSE Update license year to 2016 Jan 19, 2016 [Docs] Tweaking documentation specifying inclusion order Jan 30, 2017
bower.json v0.33.1 Aug 20, 2015
component.json v0.35.3 Jan 24, 2017
es6-sham.js [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `es5-shim`, `eva… Apr 30, 2018 v0.35.3 Jan 24, 2017
es6-sham.min.js Correct version numbers for .min files Mar 1, 2017
es6-shim.js [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `es5-shim`, `eva… Apr 30, 2018 v0.35.3 Jan 24, 2017
es6-shim.min.js Correct version numbers for .min files Mar 1, 2017
package.json [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `es5-shim`, `eva… Apr 30, 2018
testling.html [Tests] split up Map and Set test files. Jan 4, 2016

ES6 Shim

Provides compatibility shims so that legacy JavaScript engines behave as closely as possible to ECMAScript 6 (Harmony).

Build Status dependency status dev dependency status

browser support

Sauce Test Status

HTML version of the final ECMAScript 6 spec


If you want to use it in browser:

  • Just include es6-shim before your scripts.
  • Include es5-shim especially if your browser doesn't support ECMAScript 5 - but every JS engine requires the es5-shim to correct broken implementations, so it's strongly recommended to always include it. Additionally, es5-shim should be loaded before es6-shim.

For node.js, io.js, or any npm-managed workflow (this is the recommended method):

npm install es6-shim

Alternative methods:

  • component install paulmillr/es6-shim if you’re using component(1).
  • bower install es6-shim if you’re using Bower.

In both browser and node you may also want to include unorm; see the String.prototype.normalize section for details.

Safe shims

Math functions’ accuracy is 1e-11.

  • Reflect

    • apply()
    • construct()
    • defineProperty()
    • deleteProperty()
    • get()
    • getOwnPropertyDescriptor()
    • getPrototypeOf()
    • has()
    • isExtensible()
    • ownKeys()
    • preventExtensions()
    • set()
    • setPrototypeOf()
  • Symbol (only if it already exists)

    • match (and corresponding String#match, String#startsWith, String#endsWith, String#includes, RegExp support)
    • replace (and corresponding String#replace support)
    • search (and corresponding String#search support)
    • split (and corresponding String#split support)

Well-known symbols will only be provided if the engine already has Symbol support.

  • String.prototype Annex B HTML methods
    • anchor()
    • big()
    • blink()
    • bold()
    • fixed()
    • fontcolor()
    • fontsize()
    • italics()
    • link()
    • small()
    • strike()
    • sub()
    • sup()

These methods are part of "Annex B", which means that although they are a defacto standard, you shouldn't use them. None the less, the es6-shim provides them and normalizes their behavior across browsers.


The Map, Set, and Promise implementations are subclassable. You should use the following pattern to create a subclass in ES5 which will continue to work in ES6:


function MyPromise(exec) {
  var promise = new Promise(exec);
  Object.setPrototypeOf(promise, MyPromise.prototype);
  // ...
  return promise;
Object.setPrototypeOf(MyPromise, Promise);
MyPromise.prototype = Object.create(Promise.prototype, {
  constructor: { value: MyPromise }


Including a proper shim for String.prototype.normalize would increase the size of this library by a factor of more than 4. So instead we recommend that you install the unorm package alongside es6-shim if you need String.prototype.normalize. See for more discussion.

WeakMap shim

It is not possible to implement WeakMap in pure javascript. The es6-collections implementation doesn't hold values strongly, which is critical for the collection. es6-shim decided to not include an incorrect shim.

WeakMap has very unusual use-cases, so you probably won't need it at all (use simple Map instead).

Getting started

var assert = require('assert');

assert.equal(true, 'abc'.startsWith('a'));
assert.equal(false, 'abc'.endsWith('a'));
assert.equal(true, 'john alice'.includes('john'));
assert.equal('123'.repeat(2), '123123');

assert.equal(false, NaN === NaN);
assert.equal(true,, NaN));
assert.equal(true, -0 === 0);
assert.equal(false,, 0));

var result = Object.assign({ a: 1 }, { b: 2 });
assert.deepEqual(result, { a: 1, b: 2 });

assert.equal(true, isNaN('a'));
assert.equal(false, Number.isNaN('a'));
assert.equal(true, Number.isNaN(NaN));

assert.equal(true, isFinite('123'));
assert.equal(false, Number.isFinite('123'));
assert.equal(false, Number.isFinite(Infinity));

// Tests if value is a number, finite,
// >= -9007199254740992 && <= 9007199254740992 and floor(value) === value
assert.equal(false, Number.isInteger(2.4));

assert.equal(1, Math.sign(400));
assert.equal(0, Math.sign(0));
assert.equal(-1, Math.sign(-400));

var found = [5, 10, 15, 10].find(function (item) { return item / 2 === 5; });
assert.equal(10, found);

var foundIndex = [5, 10, 15, 10].findIndex(function (item) { return item / 2 === 5; });
assert.equal(1, foundIndex);

// Replacement for `{}` key-value storage.
// Keys can be anything.
var map = new Map([['Bob', 42], ['Foo', 'bar']]);
map.set('John', 25);
map.set('Alice', 400);
map.set(['meh'], 555);
assert.equal(undefined, map.get(['meh'])); // undefined because you need to use exactly the same object.
assert.equal(4, map.size);

// Useful for storing unique items.
var set = new Set([0, 1]);
assert.equal(true, set.has(0));
assert.equal(true, set.has(1));
assert.equal(true, set.has(2));
assert.equal(false, set.has(4));
assert.equal(true, set.has(5));
assert.equal(false, set.has(5));

// Promises, see
Promise.resolve(5).then(function (value) {
  assert.equal(value, 5);
  if (value) throw new Error('whoops!');
  // do some stuff
  return anotherPromise();
}).catch(function (e) {
  assert.equal(e.message, 'whoops!');
  assert.equal(true, e instanceof Error);
  // any errors thrown asynchronously end up here


  • Object.setPrototypeOf / Reflect.setPrototypeOf
    • Note that null objects (Object.create(null), eg, an object with null as its [[Prototype]]) can not have their [[Prototype]] changed except via a native Object.setPrototypeOf.
  • Well-known Symbols
    • In order to make them work cross-realm, these are created with the global Symbol registry via Symbol.for. This does not violate the spec, but it does mean that Symbol.for('') === will be true, which it would not by default in a fresh compliant realm.