Different JavaScript libraries each have their own approach to deal with certain things. For example, React relies on JSX—an XML dialect embedded in JavaScript for declaring user interface components. Lodash exposes lots of little functions, some of which can be chained together to simplify complex code. The idea behind Immutable.js is to expose a small number of collection classes as its API. How does it work?
The Immutable.js approach
A collections API
A collection in JavaScript refers to anything that can be iterated over, for example, when using a for..of loop. In practice, this means arrays and objects. Arrays and objects are collections of values; the only difference between them is how you look up values. An array is an indexed collection, because you use a numerical index to lookup a value. An object is a keyed collection, because you use a key string to lookup a value.
The issue with these primitive JavaScript collection types is that they can change; that is, they're not immutable. The collections exposed by Immutable.js feel a lot like native arrays and objects. In fact, you can take an array or an object and use it to construct an Immutable.js collection. You can also turn an Immutable.js collection into a JavaScript array or object.
This is the extent of the Immutable.js API. You use collection classes to hold your immutable data. To use this immutable data, you call methods on these collections, which is at the very heart of the Immutable.js API.
Collection methods return new data
Let's say that you have an Immutable.js collection: coll1. Then, you call a method to insert a new value into the collection: push('newValue'). This is what a persistent change looks like: coll1 persists and push() returns a new collection that includes the new value.
Not all collection methods are mutative. For example, if you want to filter a collection so that only items that pass a given criteria are returned, you would call the filter() method. This would result in a new collection, just like adding a new item would result in a new collection. The difference is that filter() isn't a persistent change—it's part of a sequence transformation.
Think of a sequence transformation as an Instagram filter. You have the original collection: the picture. Then, you have a filter() transformation, which takes the original picture data and rearranges some of the pixel data. You want to be able to see the results of the filter, but you don't want to change the original. The filter is just a view of the original.
Chaining method calls
Immutable data doesn't just sit inside of a constant. Somehow, your applications need to make use of this data. These are called side-effects. A side-effect is something that is effected by immutable data, such as rendering data on the screen in a user interface or writing data to a file. By contrast, operations performed on immutable collections are either persistent changes or sequence transformations, both of which result in new collections. These operations don't have any side-effects; they just result in new data being created. Another term used for functions that don't cause side-effects is pure functions.
With Immutable.js, you start with a collection of immutable data and work your way toward some sort of side-effect. In functional programming, it's generally best to avoid side-effects due to the problems they cause. But side-effects are unavoidable. Without them, your software cannot interact with its environment. By chaining together Immutable.js collection methods, you can write clean and concise code that transforms immutable data into something that you need—something that a side-effect can use.