Hacker News new | ask | show | jobs
by thebosz 2476 days ago
ImmerJS is a direct replacement for ImmutableJS.

We recently switched from using ImmutableJS in our Redux store to using ImmerJS.

We took the approach one reducer at a time. We have multiple reducers and we're using combineReducers (the ImmutableJS one until it was completely converted).

We had no issues whatsoever in the change. ImmutableJS doesn't care about plain JS objects (which is what ImmerJS reducers return) so everything worked as expected.

React's shallow comparison worked as expected since ImmerJS produces new objects on mutation (just like ImmutableJS).

Essentially: there is no case where ImmutableJS is needed. All functionality and benefits are available in ImmerJS which is a much easier to use library.

To do the migration, we literally just used the docs on the Github repo. This was back with version 1.0 or something and it wasn't documented very well but we were able to figure it out. The first code example is how to use it with Redux. Also the section on Currying is useful.

Edit to add: This is all within the context of web apps, specifically React apps with Redux. I'm sure there's probably some places where ImmutableJS is desirable, but I don't know of any.

1 comments

"there is no case" is a strong statement. ImmutableJS is generally the wrong tool for the job in a reducer. It's optimized for if you have a single flat object with 1000s of keys. Immer can't implement the same level of structural sharing
Can you explain this scenario further? I’ve not used immutablejs but I’m familiar with both functional data structure concepts and immerjs.

Immerjs just improves the ergonomics updating a native nested structure in a way that the original contents are maintained as much as possible. Because js has dreadful support for equality checks, this definitely comes in useful.

Immutable.js implements a specific set of data structures that internally share references. When you add a new field or copy an object, Immutable.js doesn't have to completely recreate things. For small objects this doesn't matter, but for _very_ large objects and arrays, it does improve performance to some extent.

With Immer and "hand-written" immutable updates, doing a `{...obj}` or `someArray.slice()` will do a "shallow" copy of the object. This is equivalent to what Immutable.js does in that it keeps all the fields pointing to the same references. However, the JS engine does have to do an O(n) processing of all the individual top-level keys, whereas Immutable.js's internal data structure is O(logN) or something like that. So, for _very_ large objects, it is faster for Immutable.js to make a copy than it is for plain JS data.

My take, however, is that

- Most apps will not be dealing with gigantic objects, so there's no perf benefit from using Immutable.js

- Immutable.js is a much larger dependency than Immer

- The fact that Immer works with POJOs _and_ gives you the ability to write trivial "mutative" syntax for updates is a huge improvement over Immutable.js's Java-inspired API

So, to me, the only hypothetical use case where Immutable.js would actually be worth it is if your app is consistently dealing with huge objects, _and_ there is truly serious overhead from copying them that needs to be optimized.

I added a caveat.