Immutable icon indicating copy to clipboard operation
Immutable copied to clipboard

Fast immutable data structures

How to use

Just load up build/Immutable.min.js. It works with AMD / Require.js, CommonJS / Node.js, or the Immutable global variable.

You can find documentation in the doc/doc.rst file.

You can find benchmarks in the benchmarks folder.

Quick overview

See the documentation for an alphabetical list of the types / functions provided by this library.


Dict and Set can have anything as keys, including mutable objects and immutable objects (Dict, Set, List, etc.)

You can also use SortedDict and SortedSet to define your own custom sorting.


Equality is well defined, and is based on egal <http://home.pipeline.com/~hbaker1/ObjectIdentity.html>__.

What that means is that mutable objects are only equal if they are exactly the same object, but immutable objects are equal if they have the same value.

These two mutable objects are different, and so they are not equal:

.. code:: javascript

// false
equal({ "foo": 1 },
      { "foo": 1 });

These two immutable objects are different, but they have the same keys / values, and so they are equal:

.. code:: javascript

// true
equal(Dict({ "foo": 1 }),
      Dict({ "foo": 1 }));

This is the only sane default behavior for equality.


You can easily convert to / from JavaScript:

.. code:: javascript

var obj  = { "foo": 1 };
var dict = fromJS(obj);
var obj  = toJS(dict);

You can also easily convert from one data type to another:

.. code:: javascript

var dict   = Dict({ "foo": 1 });
var list   = List(dict);
var stack  = Stack(list);
var record = Record(stack);

You can also losslessly convert to / from JSON, allowing for sending immutable objects over the network:

.. code:: javascript

var record1 = Record({ "foo": 1 });
var json    = toJSON(record1);
var record2 = fromJSON(json);

// true
equal(record1, record2);

For most operations, if the new value is the same as the old value, then it just returns the old value:

.. code:: javascript

var dict1 = Dict({
  "foo": 1,
  "bar": 2
});

var dict2 = dict1.set("foo", 1);

// true
dict2 === dict1;

This means that you can use this library with React <https://facebook.github.io/react/>, Mercury <https://github.com/Raynos/mercury>, etc. and it will be very fast.

This is also useful anytime you want to efficiently check if something has changed or not:

.. code:: javascript

var old_value = null;

// Saving to the database is expensive, so we want to avoid doing it
function save_to_database(value) {
  // Do nothing, the data has not changed
  if (value === old_value) {
    return;
  }

  old_value = value;

  // Save to the database
  ...
}

In the above function, if the immutable data has not changed, then it will be === to the old data, so we can avoid doing the expensive save operation.

This should only be used as an optimization to speed things up: you should use equal to test whether two immutable objects are equal or not.

How do you determine whether to use === or equal? If using === changes the behavior of the program, then you should use equal instead.

In this case, if the data is ===, we can safely choose to not save to the database. And if it's not ===, that's fine too: it just means we have to do the expensive save operation. So either way, the behavior is identical.

But in a different situation, using === would change the behavior of the program, and so in that case you should use equal instead.


All data types accept an ECMAScript 6 Iterable <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol>__ and can be used as an ECMAScript 6 Iterable:

.. code:: javascript

var tuple = Tuple([1, 2, 3]);

// 1
// 2
// 3
for (var x of tuple) {
  console.log(x);
}

In addition, the various iteration functions (each, map, zip, etc.) accept and return Iterables:

.. code:: javascript

var tuple2 = map(tuple, function (x) {
  return x + 20;
});

// 21
// 22
// 23
for (var x of tuple2) {
  console.log(x);
}

For developers

You'll probably need to use npm install to get the required dependencies. Every time you make a change to the src directory, you have to run npm install to rebuild.

Run the benchmarks with node build/Benchmark.js. This will take a long time (several minutes, possibly hours).

The unit tests are automatically run when using npm install, but you can also run them manually by using node build/Test.js.