Ah yes Immer is the framework I read about a few months back but couldn't find anymore. Thanks for reminding me.
> My only concerns are that the code _is_ mutating unless you wrap it in RSK's "magic" `createReducer` utility that uses Immer, and it's going to be hard to figure out how to teach this properly. But, in terms of LOC and simplicity, it's a huge win.
It's only a win since we decided that "mutation is bad" and we had to do spread notation gymnastics in all our es-2025 code that we are compiling to es5 anyway. From an abstraction point of view this is how I feel consensus about state management changed over time in the frontend world (or the part/frameworks I was involved in):
- 2010: jQuery will help you update the DOM anywhere (looking at IE6) - but you have to solve state yourself. A deeply nested object attached at `window` was considered best practice.
- 2012: We need to manage state properly, here is a nice Backbone "model" class: pass it a schema and use getters/setters to update so you can glue state change events to your view logic.
- 2014: Angular (first version) is great! Don't worry about managing your state yourself, just attach whatever you want to $scope and we will simply use dirty checking to check everything whenever something changes.
- 2015: React uses a vdom which behaves similar: change whatever you want and keep rendering it and React will figure out what actually changed. And for your state we made this flux thing which you implement as a bunch of different data stores (in my mind similar to backbone models except they only go "one way").
- 2016 (redux): here is a single store that also flows one way. Oh yea you need to do everything functional and you can't mutate any objects anymore or things will break. These 20 lines of code show you how to change the property of object with another property called id with value "x" in a nested list. This is better because it makes diffing faster in the vdom. You have to make sure you never mutate so here is a way to "freeze" your objects which will make sure you don't do this.
- 2017 Immer (I haven't used this yet): We realize it's a pain to change big objects if you can't mutate, so here is a dummy object you can mutate, we will clone it to make sure it's a different object. This is a proxy to the objects that will end up in your store (and exposed to your view layer).
I understand how we got to needing Immer, but it's a solution to a problem we only have because of how frameworks like React figure out what changed (strict equality). But it's too verbose and error prone for us to do manually. React only got designed as it did because too many people got tired of OO style state management. Right now I'm noticing a lot of people are getting tired of the verbosity, boilerplate and complex abstractions that come with doing things the "proper React way" (updating state represented in an object is the main example here, but that whole chain is verbose: you need to create actions you can dispatch, you need to write a reducer to catch those actions and mutate your objects, you need to glue the correct state to each component).
React is great tech, but in a lot of ways it's a counter movement. Countering complexities you get when managing state the OO way. But now it has gotten very complex itself, we now need a solution (immer) introduced by a solution (redux) that was needed to manage state inline with React. In other words, also very complex.
It feels almost as if I took the Backbone code, renamed it and marketed as "a simpler way to manage your UI" I could get a lot of people to switch away from React + redux + immer + immutable + redux-thunk + etc...
I wish we had more historical overviews like this.
The number of new developers has been outstripping the number of old developers in most environments and this has been happening for at least the last 15 years.
Thus, we come back to Richard P. Gabriel's Worse is Better, or at least the essay's focus on the importance of social components of a project[1]. N.B.: not implying Redux is worse than any of the other discussed projects.
Newer generations cannot possibly have the time to go through the history and tradeoffs of various frameworks that used to be extremely popular and the reasons people moved on. Too many previous frameworks and too few posts like what you just wrote. Besides, where to start? It's not like TAOCP is going to have a chronology of Browser UI frameworks.
Instead, the tendency is to leverage the rapidly developing ecosystem and work with the projects that have the largest numbers of stars on github, etc.
If you are a very large well heeled eng. organization with a capability to enforce the use of particular frameworks, it is in your interest to popularize them. You will pay and encourage your engineering org to, among other things they do, market it to the dev. community. If there are enough engineers in your org (say: tens of thousands), you will begin exerting a tremendous concentrated influence on the Open Source community.
At the same time, for everyone else who does notwork inside a 10K+ engineer org, the lack of future maintenance and upgrades presents such a huge downside risk to not using the most popular open source frameworks. The open source community moves so quickly that you run into the risk of being stuck with maintaining the reusable components you plucked from other open source efforts.
The backwards compatibility guarantees are so much lower than what they used to be. The browser world is still figuring out how to link dependencies[2], let alone generate a stack that is stable enough where you don't have to continually update your UI codebase if you want to keep continuing to reuse other people's widget code.
So you tend to stay with the pack. React is the new most popular thing? OK, let's do React. Redux is the new way? OK, Redux. Pick anything else and you risk being stuck with a stack that rapidly loses the ability to interoperate with a huge majority of new Browser UI open source code.
> My only concerns are that the code _is_ mutating unless you wrap it in RSK's "magic" `createReducer` utility that uses Immer, and it's going to be hard to figure out how to teach this properly. But, in terms of LOC and simplicity, it's a huge win.
It's only a win since we decided that "mutation is bad" and we had to do spread notation gymnastics in all our es-2025 code that we are compiling to es5 anyway. From an abstraction point of view this is how I feel consensus about state management changed over time in the frontend world (or the part/frameworks I was involved in):
- 2010: jQuery will help you update the DOM anywhere (looking at IE6) - but you have to solve state yourself. A deeply nested object attached at `window` was considered best practice.
- 2012: We need to manage state properly, here is a nice Backbone "model" class: pass it a schema and use getters/setters to update so you can glue state change events to your view logic.
- 2014: Angular (first version) is great! Don't worry about managing your state yourself, just attach whatever you want to $scope and we will simply use dirty checking to check everything whenever something changes.
- 2015: React uses a vdom which behaves similar: change whatever you want and keep rendering it and React will figure out what actually changed. And for your state we made this flux thing which you implement as a bunch of different data stores (in my mind similar to backbone models except they only go "one way").
- 2016 (redux): here is a single store that also flows one way. Oh yea you need to do everything functional and you can't mutate any objects anymore or things will break. These 20 lines of code show you how to change the property of object with another property called id with value "x" in a nested list. This is better because it makes diffing faster in the vdom. You have to make sure you never mutate so here is a way to "freeze" your objects which will make sure you don't do this.
- 2017 Immer (I haven't used this yet): We realize it's a pain to change big objects if you can't mutate, so here is a dummy object you can mutate, we will clone it to make sure it's a different object. This is a proxy to the objects that will end up in your store (and exposed to your view layer).
I understand how we got to needing Immer, but it's a solution to a problem we only have because of how frameworks like React figure out what changed (strict equality). But it's too verbose and error prone for us to do manually. React only got designed as it did because too many people got tired of OO style state management. Right now I'm noticing a lot of people are getting tired of the verbosity, boilerplate and complex abstractions that come with doing things the "proper React way" (updating state represented in an object is the main example here, but that whole chain is verbose: you need to create actions you can dispatch, you need to write a reducer to catch those actions and mutate your objects, you need to glue the correct state to each component).
React is great tech, but in a lot of ways it's a counter movement. Countering complexities you get when managing state the OO way. But now it has gotten very complex itself, we now need a solution (immer) introduced by a solution (redux) that was needed to manage state inline with React. In other words, also very complex.
It feels almost as if I took the Backbone code, renamed it and marketed as "a simpler way to manage your UI" I could get a lot of people to switch away from React + redux + immer + immutable + redux-thunk + etc...