Last month I wrote React Still Feels Insane And No One Is Talking About It and stirred a little bit of internet drama with it. First it went hot on Reddit, then it got quiet for a few days, and then happened the surreal experience of a YouTuber reading your words aloud. It was a very interesting week, and this blog post is a summary, as well as a reaction video blog post to it all.
So how big did this one go? I don't track you, the user, very much here because I don't believe blogs should do that. But I do have some server-side logs, and a bit of a custom dashboard where I can see the rough overview.
Prior to this one, my biggest blog post was the Samsung one, which is still racking up around 100 views daily. Even on its peak day, when I published it and linked it on Reddit, it only got around 4,000 views.
The React blog post has had 30,000 views in its first day, so 8x as many. The internet moves on quickly though, so this has tapered off and is now hovering at around 300 views per day. Overall, in the last few weeks, my logs say around 50,000 people have seen that blog post.
Is this a lot? On the "internet scale", this is just peanuts - the Reddit post claims to have been shown to 400,000 users, which is then 8x of that.
But my 50,000 views are still definitely past a "single person scale". It's big enough that you can't perceive how much it actually is, because you can't imagine that number of persons without reducing them to a formless mass of people. It's a number of souls that would be at a concert or a sports game. So on that scale, it seems pretty crazy that this niche essay has been read by a concert of people.
So overall, for this topic and this medium (who even reads blogs nowadays?) - it seems like a pretty good reach.
A few people have asked me if my cheap servers could handle this load. Of course they could.
I have a pretty non-standard hosting setup that I have already written about: Solar-Hosting This Blog From a $20 PC and Raspberry Pi Self-Hosting Experiments. Basically, it's all hosted from my home over a residential fiber connection with the usual 24-hour cycle dynamic IP address. These small computers are load-balanced from a VPS, so every time you refresh a page, you get served a different version from a different server.
It sounds like this cheap byzantine contraption should crash down in flames at the first sight of a concert of people coming to it, but no. Not only did nothing break, but even looking at the CPU charts, you can hardly even tell anything was happening.
Overall, these tiny servers handled around 90,000 requests on that day. But that's really not a lot - it comes around one request per second. But it's worth pointing out anyway, because I don't believe people have the intuition on how much you can do with small hardware. You can serve your website from your home, from a $20 device, to 30,000 people in a day without even seeing a blip on the CPU chart.
Of course, this all relies on the assumption that the software you're hosting is lean enough. As written in my first, obligatory blog post on how this blog is made, I've made explicit design choices to ensure those things - this is all minimal static HTML with no JS or extra API calls.
And yes, I know Twitch and YouTube can't do this. But the point I'm trying to make - without getting into any holy war again, this time with the serverless folks - is that a single server can get you further performance-wise than you think it can.
I believe this simple setup could even "scale", to use that word, to maybe even 1 million requests per day, which sounds like a lot but is only 10 requests per second - which is really not that much.
While the blog website survived just fine here, one other thing did not - the custom traffic dashboard that I mentioned before. It works pretty naively, by parsing all the server-side logs into JS objects and then analyzing them, and it does so every time you open the page to see it. This has worked fine so far, but when the log volume increased, parsing it all became too slow. I'll have to cache it somehow, or, another crazy idea - what if your server-side logs were already JSON?
For the third part of this article, I'd like to address comments and insights that I got from various internet commenters on the topic. But most of all, I'd like to address one Mr. Theodore Brown from the website of YouTube.
When I published the blog post, first few comments from the people were exceedingly negative. Vote count on Reddit went into blue. Truly I felt I had no idea what I'm talking about.
But few hours in, something shifted. Those negative top-level comments all started getting replies that countered them. It was here that I saw a) maybe I'm not that crazy and b) this topic's gonna be a hornet's nest. Eventually, the Reddit thread did change into a 75% percent upvote rate, and I felt that mostly, people agreed with my thoughts.
So with such a positive overall sentiment I was very eager to hear what an influential YouTube programmer would bring to this topic. With half a million of people watching him, I felt his take should be an interesting one either way. I didn't necessarily expect him to agree with me, but at least to steer it in an interesting direction for further discussions. But sadly, what he talked about for that hour - I think this is, on multiple marks, just disappointing.
I feel like we got off on a good start. Some agreements here and there, some good points about me using unfair language to make things seem worse than they are (completely true, I've fixed it now). But then, halfway into the video, some of the arguments first get self-contradictory, then it starts to seem he was not even trying to understand the article but just cherry-picking it to find things to roast. By the end, the video devolves into a full-on rant.
The first thing that furrowed my eyebrows happens 40% into the video. I wrote that React's "pure functions" are not actually pure and that people should stop saying that. His answer to that is this hyperbole:
I have never seen anybody talk about React components as pure functions.
Really, like no one ever? As an ironic low-shot, where he reduces my original thesis to a "skill issue" and says I should read the React docs, I can only respond by... linking the very React docs, which say this:
Components and Hooks must be pure.
Purity in Components and Hooks is a key rule of React that makes your app predictable, easy to debug, and allows React to automatically optimize your code.
Here it is in an image format too, for emphasis:

I have a few thoughts of this, some of which will again bang on the "React bad" drum. This, in my opinion, is again where React shows its misuse of functional programming paradigms. Yes, UI = f(state), that is a true and handy equation. But it's also true that state = props + hooks + context. In a mathematical way, a component is a function of those three input parameters. And in that way, it is pure.
But a component "function", in a programming way, only takes the props as its input argument. Then, it leaves "holes" inside of the function body where the rest of the state can come in through hooks. This is what I mean when I say state is "sideloaded" into components.
If you think of those "state holes" as component's inputs, then technically the component doesn't hold state - it's instead injected into it. Using that definition, which React docs subscribe to - the component is pure.
But then, component functions are not. Functions should take their inputs through function arguments, and anything that's not an argument is, in fact, a state. No matter how you name it and where you store it, or if you share it with other components, it is state. And in that regard, component functions that have hooks can't be considered pure.
So, to recap - components are pure, but component functions are not. I'm finding this mental model messy enough that I wonder why are they even insisting on mentioning purity in the docs, except for just, again, to make it sound smarter than it actually is.
Maybe if React used some kind of dependency injection system, and hooks would be passed in as input arguments, I would argue that'd be a much easier API to use and reason about. Practically it would be as equally as "pure", but it would be a much simpler model because you'd know the entirety of your component's state in its function signature.
But I guess React is too focused on being simple that they'd never accept something as elaborate as DI, but will instead misuse functional paradigms to justify making something even worse to use.
Next on, when talking about side effects, I say an API call is a good example of that. His reaction to this is an immediate facepalm and a lecture on how destructive API calls shouldn't be side effects, but actually being done as part of the click handlers themselves.
What? I mean, that is true, but it's completely orthogonal to the topic. I feel like he's just seeing what he wants to see to maximize how much he can roast it.
I'm finding it genuinely puzzling that a man of his experience can't perceive an API call could be a side effect. The example I had in mind while writing it, which coincidentally is the same one used in those React docs he likes so much, is to post something asynchronously to an analytics endpoint. So I really have nothing to comment on this exact part, because I don't think he understood it and instead picked an imaginary example to get more outrage in.
After this, he goes to fix my bad useEffect code example. Hilariously enough, he fixes it... by importing an external library. Even if it is something as ubiquitous as Tanstack Query, I still think this is pretty funny. The fact that React gives you hooks to solve these kinds of issues, then proceed to write a 21-minute read article on how not to use them, and then you still have to reach for an external library to actually solve the issue cleanly.
I only wonder one thing. The bad code example I linked was written in 2021, on a project that didn't use Tanstack Query. How did people solve this issue before that library was a thing? I sure know I've seen that kind of code often around, and I don't remember people building custom hooks to make this code cleaner, as Theo suggests as one possible solution.
Usually if you had to write a code as objectively bad as this, you had a good reason for it. For example, let's say you have two pieces of state coming from two different stores. While they're usually very separate, just for this one component, you need to make one depend upon the other. You're faced with a choice: either you re-architect your app state so they're not separate anymore; or, you write this ugly useEffect chain. And sometimes, the more pragmatic solution would be the latter.
To dismiss this entire problem as a "skill issue" and imply all is good now because an external library solved an issue that React will allow you to do is very curious to me. My first impression here is, again - maybe the hooks are a conceptually wrong model when it took so many years and an external library to be able to work with them.
After that, there happens the most egregious part of the video. He opens up his code and says "honestly, we don't even use effects that much". Then, he proceeds to show 85 usages across 34 components, which excluding imports, comes to "just" 1.5 per component. Worst of all, he shows some of them where it's apparent he's using all the bad practices he just said are "bad code" and "no one does anymore". Here is his useEffect making both an API call and setting a state:

And then, just a few mins later, at 29:17 of the same video, Theo confidently claims:
"There is no place in our codebase where useEffect triggers some external thing, like a fucking API call."
But you know what, I actually get it. And that was my point in the original article - this separation of "app stuff" and "side effects" is theoretically a good idea, but in practice those two things are so intermixed that separating them is impossible. Which is to say again - that hooks and especially a side effect hook might be completely wrong abstractions to use when making web apps.
After this, there's a complete audio-visual mismatch on what he's showing and talking about. He goes to search for other instances in the code and says "useState comes up almost twice as often" while showing he doesn't actually use it that much. Then "we use useQuery a lot", but shows only 24 instances. People have noted this in the video comments. I don't understand why this part wasn't at least edited out - I guess it shows how much effort really goes into those videos.
Many times during a video, he reduces my thoughts to a "skill issue", saying I should read the React docs before writing anything. Well, it is true. I haven't read these docs.
It is also true that I have read the docs. I have read them all the way back in 2017 when I first started learning React. I have also read them again in 2022, when I started working with it professionally. And from what I can remember - those two were completely different docs.
You would think you can come back to a technology after three years and still be able to work on it - I mean, how much can it change? In any other stack, that might be true, but in frontend development, and React especially so - it's too naive to think that. Hell, the "You Might Not Need an Effect", a 21-minute required read telling you how NOT to use a thing React gives to you, was only added three years ago.
So it's kind of a Schrodingerian documentation - every time you check it out, it collapses into a completely different website.
To be fair, the "bad code" example I gave in the original article is maybe too bad or too junior to be taken as a serious argument for anything. But people on Reddit have pointed out that the mere fact you CAN do those things, without the compiler or the runtime preventing you, simply means React is after all, a pretty bad piece of software.
Good software should be smarter than you. It should prevent you from making dumb mistakes. Take for example Rust and its borrow checker, and how many hours people spend fighting with it, but in the end, the code is better for it. On the contrary, React keeps its un-opinionated, hands-off approach through and through, allowing you to do whatever you want, resulting in such "junior-level" code that only a human code review can prevent. I interpret this very clearly as yet another "React bad" argument.
Theo, however, has a different opinion. He claims that this shows React is actually great, precisely because it still works despite the nonsensical code you throw at it. However offensive the code you write at it, React will still work, and it's great because of that.
I think it's interesting we can follow the same arguments to completely different conclusions, so I guess we're all just seeing what we want to see.
Or, as one commenter has pointed out - maybe we're completely missing what Theo's incentives in all of this are, and maybe this "truth" thing just isn't it. Suspiciously enough, those comments have since been deleted, but I have snapped a screenshot that I will share here simply because of that.
Frankly, I really don't care about React. I had fun discussing it with people last month, but honestly, next week I'll be working on something else and React won't affect me a bit. For this reason I didn't even reply on any of the Reddit comments, as it was not my discussion to partake in.
But then the YouTube video came out. I have written my thoughts on React above, but what I really wanted to write was this chapter: on the sad state of the discourse on YouTube.
So as I said before, I expected some interesting takes from a YouTuber of that caliber, hoping it could start some discussion on a topic which obviously has some interest around it. In the end, it all felt pretty dismissive and reduced to a rant.
I don't spend a lot of time on YouTube. I know the internet can be a toxic place, and YouTube especially so, but I expected better from channels that are not about gaming, sports, or reality TV - but about work.
But I guess even there it's okay to dismiss someone's arguments as a "skill issue" and say people are "low-IQ" for writing code like that. I could understand these things happening on more anonymous platforms, but here it's a man using his real name and a face to deliver Reddit-level comments.
I don't want to attack the man, because probably there's a deeper truth that a) outrage buys you likes, shares and subscribes; and b) with a sponsor list like his, you can't really go against your cash cow.
But still, it's obvious this man knows his stuff and people watch him to learn things, and they maybe even consider him a role model on how a programmer should talk and walk. But what kind of impression is he sending?
Is this how a person acts when faced with something that challenges their worldview? More importantly, as his rant made it clear he considers me his inferior - is this how we should talk to our inferiors? I imagine the world would crumble to pieces if all of us brought that communication style to our day jobs. House M.D. is not a documentary - first and foremost because in a real professional setting, no one gets away with talking like that.
So on this human-to-human level, not even taking all the technical mistakes into account - I'm just disappointed. We could've had a good thing going here, man.
Let's end this blog post like the video does, by talking about target=blank. Theo ends the video by getting one more quick rant in. I believe he's wrong about this, but more importantly, he's wrong in a way that completely explains all the other things he's wrong about too.
He says: "This guy is not good at building things" because, as he points out, the links on my blog sometimes open in a new tab, and sometimes they do not.
Firstly, this is not true - all of them open in a current tab. And secondly -
Fwoosh - a digression. I don't consider myself a React expert, nor did I write my original article pretending to be one. But I do think that, sometimes, one pair of fresh eyes might be worth more than a few of the experts' ones.
The exact perspective I had in mind while writing it was this - people writing React have gotten so used to it, adding stuff to it over the last 10 years, increasing the complexity just slowly enough that they don't notice what they've actually built.
Let's say a junior engineer joins your team. He looks at the code, which is ages old, and asks you: "Why do we call ZFLORP as part of KHROMPS?". You start to reach for your canned response - the one you've merely inherited from the company's forefathers that have been repeating it for the last twenty-five years. "We need it because-" But then you stutter a bit, and think for a very long second.
"Now that you say it", you pause dramatically, "no one has asked that question in years." Enlightened, you realize things have changed enough that, yes, you don't need to call ZFLORP as part of KHROMPS anymore. You thank the junior engineer for his fresh perspective and delete ZFLORP from your project.
Being an expert means being deep enough that it becomes hard to keep evaluating it realistically as things around it change. This is how the experts can be wrong. And how sometimes only a fresh perspective from an outsider can trigger the change, if the experts are to be open to accept the conflicting worldviews.
So to get back to target=blank - you're wrong at thinking that behaviour is somehow a bug, when in reality it's a conscious design decision that anyone could make - if they could think about things instead of just repeating what everyone else is doing.
I say this because I vividly remember having that exact discussion with myself six years ago, when I was building this blog. At the time, I too was entrenched in the "SPA-by-default", so initially, the links were all being opened in new tabs. It's just how you do it in SPAs.
But at some point I thought - why? This is not an app with a local state, so I don't need to defensively do target=blank to prevent the user from moving away from it.
Quite the contrary, without it I don't assume anything, but actually give the user the freedom to choose how he wants to open each link. Realizing that, I removed target=blank from the project completely and it's been working like that ever since.
This is what it means to think through a feature on a case-by-case basis, instead of just doing whatever is in your muscle memory. By bringing this up, Theo again shows how quick he's to judge based on his "SPA-by-default" worldview - which just does not apply universally.
The most ironic part in all of this - my entire thesis on this topic was targeted exactly to people like these, who are so deeply entrenched in React that they can't see their way out of it.
But, as it usually goes, the people who need to hear the advice the most are exactly the ones who are also most likely to reject it.
-----
(I won't be making an "official" Reddit thread for comments this time. Feel free to start one yourself if you'd like. Thanks, and until the next time!)