You don't need a library. Just have a policy that everything should be immutable by default and only turn into mutable objects when optimizing, for example for-loops. The benefit with immutability is not performance (it's actually slower) but manageability and debug-ability. It's easier to reason about code when the variables doesn't change, and you'll get all the variable-states when debugging.
Example:
The "Performance" section of Facebook's own React docs has this line at the end:
"Immutable data structures provide you with a cheap way to track changes on objects, which is all we need to implement shouldComponentUpdate. This can often provide you with a nice performance boost."
What I don't really get is, if you've implemented PureComponent and shouldComponentUpdate wherever possible, how can adding Immutable possibly improve performance? I.e. if your components are ASSUMING their inputs are immutable, how does throwing errors on mutation attempts actually speed things up?
What I don't really get is, if you've implemented PureComponent and shouldComponentUpdate wherever possible, how can adding Immutable possibly improve performance?
The argument is that if you prevent mutation then you can rely on only a shallow comparison of the object references as a reliable test for whether any of the data has changed. Your shouldComponentUpdate implementation becomes a one-line equality test for each prop that might change, or the equivalent. This may be significantly faster (and potentially easier to maintain) than any more detailed comparison of props to decide whether anything significant has changed in shouldComponentUpdate.
Of course, this doesn't address the performance implications of maintaining your state in some sort of immutable data structures rather than just mutating it. Nor does it address the performance implications of using a library like React that declaratively renders your content and does the whole vDOM diff algorithm thing instead of just poking the DOM in exactly the required places. Both of those strategies can be orders of magnitude slower than the alternatives, and both of them can cause architectural and maintenance headaches of their own, and so the questions in those cases are whether the performance is still good enough and whether the benefits in other respects outweigh those costs.
With immutable objects, you can compare them (obj1 === obj2) and assume that if they're the same, none of the properties have changed. You don't have that sort of guarantee with normal JavaScript objects, so you need to do a deep comparison.
If your component's state and props are immutable objects, then shouldComponentUpdate becomes a much easier problem to solve.
The standard, non-library way of handling state in React is to use plain old mutable Javascript objects, and just pretend they're immutable (i.e never perform any mutable operations on them). The popular claim is that Immutable "enforces" immutability, leading to less "accidental mutation" bugs. (A claim which is bogus IMO. 0 !< 0)
No, I'd say it's a _fairly_ valid claim. You have to interact with Immutable.js objects using its API, and every update API call returns a new instance. So, it _does_ generally enforce immutability. As far as I know, the only way to accidentally mutate stuff with Immutable.js is if you insert plain JS objects inside an Immutable.js object, and possibly also use one of its "update this using a callback function" methods and misuse things inside the callback.