Immutable.js is an awesome library for creating Immutable collections of data, hugely popular for React/Redux development, but not blessed with great documentation. Struggle no more, with this first in a series of in-depth tutorials, complete with live coding examples.

What is Immutable.js?

Immutable.js (or just Immutable from now on) is a library for creating collections of data, which, once created, cannot be changed. These collections are modelled on JavaScript’s Array, Map and Set objects, but with the significant difference that all methods to add, delete or update data in a collection do not mutate (i.e. change) the collection being acted upon.

For example, Immutable’s push() method, which adds an item of data to an Immutable List, actually adds the item to a new copy of the List, leaving the original List collection completely unchanged.

To see this, the following shows a standard JavaScript Array’s push() method acting on (and mutating) the array itself:


// Standard mutating JavaScript Array push
const collection = ['ironMan'];
collection.push('captainAmerica');

// Output:
collection;

In contrast, the Immutable equivalent shows the original List completely unchanged:


// Immutable.js non-mutating List.push
const collection = Immutable.List.of('ironMan');
collection.push('captainAmerica');

// Output:
collection;

In this example, collection's push() method makes a copy of collection and pushes the new item onto the copy, leaving collection itself completely unchanged.

To see the result of the push() method, we need to assign a new variable to it, as push returns the copy.


// Immutable.js non-mutating List.push
const collection = Immutable.List.of('ironMan');
const newCollection = collection.push('captainAmerica');

// Output:
newCollection;


Getting your head around Immutable collections

Immutable lets us create complex objects comprising such things as JavaScript objects, arrays, or even nested arrays of objects with arrays, with each complex object acting as an unchanging value. However, this is difficult to picture, as we’re so used to JavaScript objects containing properties with constantly changing values. Think of a user object, for example, containing properties such as username, emailAddress, age, etc. These values could change at any time.

With Immutable collections, however, the values of such properties can never change. How do you visualise this, let alone act on it?

There are two ways that might help make this concept more concrete.

Think of Immutable data as a value

An immutable collection should be thought of as a value, such as a number. A number never changes. The number 7, for example, is always 7. If you add 1 to 7 you get a new value (i.e. 8 – you knew that, right?!), but that doesn’t change 7 itself – it’s still 7.

Going back to our collection examples above, an Immutable collection is no different from a number. We can add an item to our collection, but that doesn’t change the original collection itself. Indeed, we can think of the collection’s push() method, which adds an item to an existing collection, as being equivalent to an addition operation on a number, which adds a new value to an existing number. In both cases, the original value – the collection and the number – are left completely unchanged, and a new value is returned.

This is the essence of Immutable data.

Think of Immutable data as representing the state of data

Another way to think of an Immutable collection is to think of it as the state of its data at the specific point in time that the collection was created. Whenever we query that collection, we always get the state of its data that existed at its moment of creation. We might move on in time, but the collection itself never does.

So whenever we query a collection to retrieve its data, we’re not saying to the collection “give me your data now”, we’re actually saying “give me your data as it existed when you (i.e. the collection) were first created.”

It’s the difference between asking “Who is the President of the United States right now” – which obviously depends on when you ask the question – and “Who was the President of the United States on August 13th 2016” – which is a fact that will never change.

Accordingly, any operation you perform on the data within an Immutable collection (e.g. add or remove an item) will change the state of that data at a later point in time, but the state of the data as it existed before the operation remains unchanged. What you’re left with after the operation is two collections – the first represents the state of the data before the operation, and the second represents the state of the data after the operation.

The following example may help to clarify this:


// state1 = the original state of the data at the time of 
// its creation: time 0
const state1_time0 = Immutable.List.of('ironMan');

// state2 = the new state of the data at a later time (time 1)
// i.e. after a push operation has been performed
const state2_time1 = state1_time0.push('captainAmerica');

// state1_time0 never changes, as it always reflects the state 
// of the data at time 0
state1_time0;

How to perform operations on Immutable collections

We’ve seen how to think of Immutable data; now we need to know how to operate on it. Immutable is a powerful library for manipulating our collections of data in a safe, immutable way (the clue’s in the title!).

But it’s not a small library, and has many edge cases that can trap the unwary. Because of this, performing operations on Immutable collections is not something that can be explained easily in a single blog post. Well, not in a short blog post anyway!

So here’s a collection of in-depth blog posts, each focused on one part of the Immutable API.

Enjoy 🙂

P.S. I originally concluded this post with a bit of a rant about the quality of Immutable’s documentation and its reliance on auto-generated docs, which have few examples and API signatures written in TypeScript.

However, I clearly offended a few people in the Open Source Community, which was never my intent, so I’ve removed the rant. The current issues some people face regarding the documentation (and what I was complaining about) can be found here, here, here, and here (and doubtless other places as well!).

Comments
  • Harvey Specter
    Posted at 1:36 am Nov 11, 2016
    Sean Levy
    Reply
    Author

    Awesome thank you for sharing

  • Harvey Specter
    Posted at 11:11 am Nov 27, 2016
    bob
    Reply
    Author

    I’ve heard immutable for a long time , but get no feeling about it . you make me excited again.Thanks for sharing.

  • Harvey Specter
    Posted at 11:48 am Nov 27, 2016
    rosdi
    Reply
    Author

    One question isn’t answered here, WHY would we want to use immutable.js? Why is it better than x?

    • Harvey Specter
      Posted at 6:52 pm Nov 27, 2016
      Mike Evans
      Reply
      Author

      Funny you should ask this – I’ve just submitted a pull request to the Redux docs answering exactly that question. I’ll link to it once it’s been approved.

      Tl;dr: using an immutable library of any form (for Immutable.js is just one of many) makes reasoning about your data much easier in large apps, as you know your data can’t be changed arbitrarily elsewhere; there are performance wins if you need to check whether two objects are equal, as you only need to do a shallow comparison (and libraries such as React do lots of shallow comparisons); and with Immutable.js, it offers an incredibly rich and performant API that enables data to be manipulated easily.

  • Harvey Specter
    Posted at 4:55 pm Nov 27, 2016
    Brent
    Reply
    Author

    The documentation is open source and you’re welcome to submit pull requests to improve it. It would be more productive than saying someone else’s work sucks and more impactful than writing articles on some random blog, which reeks of self promotion rather than actually wanting to improve the state of documentation.

    • Harvey Specter
      Posted at 7:00 pm Nov 27, 2016
      Mike Evans
      Reply
      Author

      Hmmm, bit harsh. The Immutable.JS library is huge – far too big for just me to cover it all, and I spent two months writing the tutorials you see here in this random blog. Indeed, the task is so big, I wouldn’t know where to begin, particularly as the API docs are auto-generated from the code.

      Equally, I wanted to use the Klipse script to enable readers to play around with the code examples, as in my experience, that’s the best way to understand what’s happening with Immutable.JS code.

      I’m more than happy to submit PRs to open source code – I’ve already done that with the Klipse code editor project, and have just submitted a PR to add to the Redux documentation. But IMO, Immutable’s documentation requires much more than help from the community – it needs the devs themselves to begin fleshing it out in a more readable way before those of us who use it start that task. That’s how I feel about it, anyway.

  • Harvey Specter
    Posted at 5:45 am Mar 6, 2017
    nenad
    Reply
    Author

    Thanks for the tutorial on immutable, haven’t started yet but already your web site looks like a good resource for JavaScript.
    Cheers, keep up the good work.

  • Leave a Reply to Sean Levy
    Cancel Reply

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>