Interesting philosophy is very rarely an examination of the pros and cons of a thesis. Usually it is, implicitly or explicitly, a contest between an entrenched vocabulary which has become a nuisance and a half-formed new vocabulary which vaguely promises great things.
Richard Rorty
I recently came across React.js: The Documentary at the end of a YouTube rabbit hole. It’s a fascinating glimpse into the history of a library that now dominates frontend web development.
What immediately stands out is how contingent the emergence of React was. In hindsight it’s easy to imagine that a web framework backed by Facebook was inevitable. Today, the concepts that it pioneered—the Virtual DOM, JSX, uni-directional data flow, component-based UIs—are so ubiquitous that it’s difficult to imagine a frontend landscape without them. But the story that emerges from the documentary is not one of Big Tech inevitability, but rather a motley crew of young developers overcoming the odds to bring a radical idea to life.
Along the way, if a couple engineers had not gotten on board, or if a Facebook manager had vetoed a months-long React rewrite of their critical ad creation workflow, or if an unproven React had not been brazenly chosen for the post-acquisition development of Instagram’s web platform, the whole thing might just as easily have fizzled out. Even after proving itself in production within Facebook, when React was open-sourced at JSConf in 2013 it was received by the frontend community not with a lack of enthusiasm but with outright hostility.
How did this happen? How does a framework go from dead on arrival to the most used library on the web in less than a decade?
In the opening pages of Contingency, Irony, and Solidarity, Richard Rorty makes the assertion that “interesting philosophy is very rarely an examination of the pros and cons of a thesis.” This is a classic Rorty head-scratcher. Isn’t examining the pros and cons of a thesis the primary thing folks do in philosophy?
He continues: “Usually it is, implicitly or explicitly, a contest between an entrenched vocabulary which has become a nuisance and a half-formed new vocabulary which vaguely promises great things”. In my reading, Rorty is making a historical observation, not a value judgement. Many of the things we now look back on as major turns in the history of ideas were not continuations of existing ideas with minor academic squabbles around the edges. They tackled problems so foreign to those being asked, in language so different from that being used, that they were seen as an intriguing novelty rather than a threat. Then they crept up on people, who found themselves almost subconsciously using the new words and asking the new questions.
Rorty’s characterization of interesting philosophy applies equally well to React. It was a half-formed vocabulary filled with unproven new concepts and mental models.
Every other framework at the time [was doing] two-way data binding and… it was like, forget about data binding, we’re not gonna do that at all. Anytime anything changes we’re just going to re-render.
Consider the initial reactions of people who would go on to be core contributors and evangelizers of the library: “Honestly I thought it was completely crazy… there was no way that was going to work.” “The whole bid here was that this would be simpler, but I can’t help but feel like this is really complicated.” “It was so far outside everybody’s idea of how things should work.” The syntax and structure of React code looked entirely different from existing web applications, and the problems that arose in React apps were foreign. But it promised something great.
In the documentary, Christopher Chedeau relates a meeting he had with Jordan Walke about the nascent React in which he asked, What is the most difficult thing to do in the frontend right now? Jordan’s answer was updates; specifically, finding and changing individual DOM nodes. Anybody who has worked with jQuery can confirm that this is indeed a painstaking processes.
If you ask web developers today the same question, nobody will talk about finding and updating DOM nodes. When you write applications in React, updating individual DOM nodes is not something you spend much mental energy on. To be sure, it’s is still doing this under the hood (and understanding precisely how is an invaluable skill). But the problem is abstracted behind the framework. In fact, having to manually reference individual DOM nodes or imperatively update them is often a sign that your code can be improved.
Rorty argues that the method of philosophy he advocates “does not pretend to have a better candidate for doing the same old things which we did when we spoke in the old way. Rather, it suggests that we might want to stop doing those things and do something else instead”. Similarly, React did not propose a better candidate for what was once the hardest problem in frontend web development; it suggested that we do something else entirely. And the same applied to numerous aspects of developing applications, from file structure to separation of concerns to mental models to state management.
Of course, countless hours of engineering and design and advocating, as well as the backing of Facebook, were a big part of why React came to fruition and persisted through intense derision. But React also succeeded because of its lack of incrementalism; its rejection of best practices; its rephrasing of the core questions. React did not solve the old problems of frontend web development. Rather, it dissolved them by rephrasing how a web page is rendered. It replaced them with new, slightly less annoying problems. React vaguely promised great things, and as people tried it out, they discovered that it delivered.
A decade later, the tables have turned. When React was open-sourced, JSX was the most mocked aspect of the library; now JSX feels more natural than HTML. Having done most of my professional work in React, I often find it difficult to shift into an imperative mental model. When I want to play around with a new web API, I don’t add a <script/>
tag to an HTML file; I fire up a simple React app.
The fact that React is now thoroughly entrenched means that perhaps we should be on the lookout for another new vocabulary that vaguely promises great things. I think local-first software is a great candidate. I noted earlier that React developers would be unlikely to cite updating DOM nodes as the most difficult problem in frontend web development. So what would they say? My answer would be synchronizing state. And just as React dissolved the question of updating DOM nodes, nascent local-first projects are all about abstracting away the problem of state synchronization. Similar to React’s ‘just re-render everything’ idea, the local-first ‘just cache everything’ ideal seems absurd when you first hear it. But on further reflection, it becomes tantalizingly simple. That will never work... right?! There’s only one way to find out.