Why not use Object.freeze for immutable JS objects?

Erik Marks from MetaMask wrote: @danfinlay and I were recently talking about how to achieve object immutability in JS. He recalled discussing the matter with Agoric, and that Agoric uses something other than Object.freeze internally. I am trying to understand the limitations of Object.freeze, and alternatives to it. If anyone at Agoric or otherwise has any insight, I’d greatly appreciate it.

Per the MDN article it seems to me that freezing small - whatever that means - objects recursively with Object.freeze ought to be fine in many cases. I suppose Immutable.js exists when the objects to be frozen are neither simple nor small. However, that library can significantly impact performance, in addition to having an API that tends to propagate throughout your code.

Mark Miller provides an exquisitely succinct answer here.

"Freezing only freezes properties. JavaScript objects can hold mutable state that is unaffected by freeze. The harden function from Agoric/harden freezes everything it can find by transitive own property traversal[*]. If harden(obj) returns successfully, then all the object reachable from obj by own property traversal and inheritance are frozen. Usually, the most useful way to think about harden(obj) is as a way to make API surface tamper proof, rather than as a way to achieve immutability, aka, purity" continued