Thanks for the insightful explanation. Adding <a href="https:&#x2F;&#x2F;github.com&#x2F;atmin&#x2F;freak" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;atmin&#x2F;freak</a> to the comparison (disclaimer, I&#x27;m the author):<p>* it supports set operations, `model(‘fieldName’, newValue)`, like Backbone and unlike Redux, which trigger only the necessary update actions in the (implicitly built) dependency graph. set is idempotent, even if your computed properties have side effects<p>* it has .on() method<p>* &quot;You can log every action and see the entire state tree before and after the action.”. In freak, too:<p><pre><code>    const model = freak(statePOJO);
    const history = [];
    model.on(‘change’, prop =&gt; {
      &#x2F;&#x2F; change is called exactly once per mutation
      history.push({...model.values});
    });
</code></pre>
freak’s README is a literal test suite, consisting of state changes and assertions.<p>Probably it&#x27;s a good idea to add &#x27;beforeChange&#x27; event, to make it possible to cancel a mutation.<p>* it&#x27;s currently implemented internally using mutable data structure, but this is implementation detail and can be changed to immutable data in the future, allowing simply `history.push(model.values)`