No One Ever Got Fired for Choosing React
jake.nyc
jake.nyc
A problem with React (or any big library really) is that sometimes developers use it for blogs, forms, or other simple websites. There are many great tools out there for these websites, React is not one of them.
Such as?
I use it for my blog and love it.
This seems like an odd value proposition for a static site generator.
Even a really shitty, unoptimized single threaded non-incremental build system shouldn’t struggle too hard to compile a static site. And even if it does, if it has a good amount of features, it shouldn’t be a problem for most use-cases.
But most Wordpress-based personal sites I've come across are significantly slower than the React-based personal sites i'm aware of. There's a big problem with abusing plugins that haven't been designed with any kind of performance in mind.
My point was that the amount of client-side bloat in a Wordpress personal site seems to be higher than the equivalent React site, and the overall performance seems to be worse.
Wordpress is a much better starting point from a SEO perspective than a react app built from scratch.
Performance is quick if you put it behind a CDN and disable things like comments (which I suppose you also wouldn't have in a react blog, unless you're building a commenting system from the ground up, too)
People building personal sites with React are mostly starting from one of the popular frameworks, these give you pretty sensible defaults for both performance and SEO (for which performance is now a factor).
If you want a blog, stop fucking around with your configuration and write.
Agreed — this was the point of the article. Tooling is a distraction from what you wanted to do in the first place. Just pick the one you can get the thing done with, whether it’s Hugo or Gatsby or WordPress or whatever.
Starting to see this on my team, example would be a simple marketing landing page, then for what are perfectly normal things you’d have on the page like a video player or a button they start using the components built for the web app.
Then you ask them for things to behave a little different or for some of the normal things you’d expect on a marketing page like a video auto playing silently with subtitles. Then you just start getting told “nah it’s too much work the component wasn’t built to do that”.
It should be the type of thing that’s written once and lasts forever with only small changes.
In my mind the mental model shift towards completely modular components including their CSS(in JS), behavior and Dom/html(jsx) is just a very pleasant front end development model.
Its hard to go back to the old ways once you have experienced the productivity of React. I say this while obviously acknowledging dealing with the tooling ecosystem can be frustrating at times.
- The ability to specify that a given component is static and should never hydrate (and never bundle in the build as a result). There’s a bunch of proofs of concept of this out there, it’s definitely a better UX, but it’s not a good DX. It’s a fight to set up, entirely manual, and generally opt in (which means you’re more likely to ship broken components if you forget to opt in, whereas opt out is more likely to deoptimize by mistake)
- Static analysis to determine where components are constant at build time and automatically strip them from the build/hydration flow.
- Compile to DOM operations like Svelte.
Basically, I want a Svelte build with a React/JSX interface.
I’m certain it’s possible, given a long enough timeline. I’m not sure how well it would work with real world React code, as hooks and context could deoptimize whole pages in unexpected ways. And that’s frankly where I wish for a much simpler React subset for this use case.
If React didn’t exist, every team member would have their own way of writing up, I don’t know, a multi-select drop down component. With React, you can nip a little bit of creativity out of each individual team member for sanity’s sake. You would be shocked just how different people’s mental models actually are without a framework.
I already go nuts at how some people structure some components, and to keep this post at peak hyperbole, I’d give up on life if I had to see their vanilla js components.
It would be unmanageable emotionally. I’ve seen some people write components that are straight up php-like includes (e.g import ‘./FilterCategories’. Doesn’t take any args. Just for sanity’s sake, the fact that React is helping teams write composable/reusable modules (or that a module is a function that takes params, so don’t be a dick and make a shrink wrapped component with vars baked in), with brain-dead ways of wiring up component logic is probably one of the most stress-reducing advents in frontend.
Lots of finger pointing by me here, but I’m doing it to vent to strangers, instead of taking it out at work.
I didn't think this was a mystery. It's because a lot of devs are coming into the web ecosystem having primarily learned frameworks at boot camps (or on their own).
Most front-end devs that I've worked with who started in the last 5-10 years have such framework-specific knowledge that they can't really jump between frameworks or work on vanilla JS.
I'm not saying this is categorically bad. I use heavy abstractions on top of web languages (TypeScript, Webpack, Sass, Svelte) even for static sites, so I'm not arguing that they should be writing vanilla JS.
It's just interesting that JS is so flexible, and some of these abstractions are so strong, that you can learn something like React without really learning JS at all. It's like a DSL on top of JS.
Otherwise if you don’t use JSX then you get something akin to programming with Ruby on Rails or Django - still quite integrated, but the syntax is familiar.
I meant that the JS you write in React, Vue, and Svelte feels like a DSL.
I admit that Angular adds some overhead if you have not worked with modules and observables, but it does give you a complete toolset to build very scalable frontends.
And once you dive into ngrx and its ecosystem it becomes clear that Angular has quite some upsides, especially for enterprise software.
There is a reason why NestJS adopted a lot of Angulars patterns such as modules and services. They make the code so much cleaner when used properly.
Build the app in such a way that you can change it. Or just use react-router.
> wether we should write class-based or functional components
Functional
> Or wether to use dispatchToProps or hooks.
Hooks.
But I see what you mean, React's idiomatic patterns do change. Thing is, if you have a class based component you can still use it in amongst your functional hook-based ones. It's still compatible.
Also I don’t understand why everyone is building with and hiring for react.
Its main selling point is that it is "just a library, not a framework" which I also find to be its biggest disadvantage. When I build an application and I choose SPA, I want a framework, not a loose collection of libs.
It’s a little like Django vs Flask. Sure Flask has less overhead but if I know what I am doing I can do 4 times as much with a framework like django in the same time, given that I know what it can do for me. Because I don’t spend time (more or less consciously) reinventing the wheel
> The first hurdle came when a component needed local state. I could have lifted it to the singleton, but that would have broken the component’s encapsulation. I noticed that lit-html directives can keep state, so I decided to use them to build a tiny component library — ignoring a warning from the lit-html developers that this wasn’t a supported use case.
> My home-brewed library worked great… until I needed to run some code when a component appeared on the screen. I started digging through lit-html documentation and issues looking for a way to detect a directive’s lifecycle, but it became clear to me that going down that path would be painful.
So the author knows about lit-html, good. I guess the obvious question at this point is why didn't he continue down the lit path he was already on, and tried lit-element? Lit-element should have given him observable local state (it's class-based web components), and would have given him lifecycle hooks (e.g. connectedCallback for doing something when a component appears on the screen). Lit-element is from the same ecosystem as lit-html; yet the author doesn't seem to have explored it at all. Why?
lit-html is entirely intended to be used with web components, which is can only create HTML and has no special support or syntax for components. As you note, LitElement is what you should use if you like lit-html and want components. We'll be making this more clear soon by bringing lit-html and LitElement closer together in documentation.
Sometimes it's justified, sometimes it's completely overkill and you waste a lot of time. On a project I've been on I've seen days being wasted to build a basic account management form (think username, password, personal details, etc) in React for no reason, despite the same being achievable with our backend (Django) in a couple hours.
Our team has never felt more productive and the dev learning curve is much less steep. Clients are happier with the results, and the apps feel much more maintainable because there are less pieces to break / update / manage in the production environment.
From what I read here, what happened here is that this developer has good knowledge of React for having used it repeteadly in the past. At the same time, he did not have experience in lit or svelte. He hit some issues and then went back to the things he knows better. It is more comfortable and more productive, there is no doubt about that. The conclusion is more like, you will write your app faster in the language, environment, and framework that you already master. I agree with that. Change one of those, and you will go through some moments of loneliness. Change two of those, you may just fail the project entirely.
What is true, and proven by many data points, is that you can write complex applications with lit-html, svelte, elm or just vanilla-JS. GitHub is not a web graphics editor but it is entirely vanilla JS. Hum, po*n apparently use plenty of vanilla JS too (https://davidwalsh.name/pornhub-interview). IBM implemented their Carbon design system in Svelte. Adobe's adaptive color tool (https://leonardocolor.io/?colorKeys=%236fa7ff&base=ffffff&ra...) is entirely in vanilla-JS. The list is long.
So what we have here is one anecdote from one person. All data points issued from real experience are welcome, valid and useful but we should be careful to not get to conclusions too fast.
Two key points there are that React's setState(..) approach to minimize redrawing is a premature optimization (which then leads to wastelands of endless opaque boilerplate like Redux) -- and also JSX is completely unnecessary and counter-productive compared to just using HyperScript API to define interfaces in plain JavaScript/TypeScript without needing to introduce extra compilation steps or more complex tooling. Another key point is that Atomic CSS like Tachyons and similar approaches obviates the need for all kinds of specialized CSS encapsulation complexity. Mithril and Tachyons leverage the flexibility of HTML, JavaScript, and CSS without trying to reinvent too many other complex layers above them -- layers which typically just create more problems in the end via accidental complexity unrelated to actually creating UIs.
In general that analysis applies to most current JavaScript-based UI libraries. Elm (which perhaps helped inspire Mithril as a vdom) or ClojureScript or other similar tools might be exceptions though for people willing to put the time into learning those languages (which compile to JavaScript) and dealing with integration issues.
So, in reading the article and also much discussion here and elsewhere, much of that verbage to my mind fits into the category of seeing (yet again) inexperienced or otherwise constrained developers picking one problematical tool and struggling with it and then jumping to another one with different (perhaps lesser) issues again without having broadly surveyed what is out there or understanding key concerns like simplicity. Of course what is much more painful is working in organizations where such faddish choices are then forced on developers who know better (as is often the case, including sadly why I know so much about Angular and React even after years of experience using Mithril successfully).
That said, once a critical amount of time and money has been spend in getting developers to use a particular solution like React, then yes, there is the sunk cost which makes it easier for an organization to do other projects in it and maintain them. Just like why a lot of other legacy software persists...
Just like Facebook could promote React aggressively over alternatives (even when React had the problematical patents clause in its license), I'm reminded a bit of when Java overtook Smalltalk in part due to huge amounts of money pumped into advertising and promoting it (including by IBM, which ironically eventually had two good Smalltalks of its own).
Every tool has its strengths and weaknesses in different situations (including Mithril and Tachyons). And I can accept that broad industry adoption is a plus for any tool for availability of developers and third-party libraries. Still, it's sad for me -- after having implemented UIs for about four decades in hundreds of different ways -- that when I find something like Mithril that works really well for current needs and has (all things considered) great developer ergonomics and a great (if small) supporting community, it is mostly ignored. While Mithril+Tachyons+ES7 works differently than Smalltalk and related UI libraries, that combination makes UI development almost as fun as it was in Smalltalk -- but with broader reach because HTML+CSS+JavaScript is now everywhere. For good or bad, I guess Mithril will remain a "secret weapon" like Smalltalk used to be. :-)
That said, the problem described here about picking something more “vanilla” but ending up with a non-standard codebase makes me long for the days of Ruby on Rails, especially before Engines, when it seemed like you could open any web app in existence and would be productive on day one just by knowing the Rails conventions...
I don't feel the same so true for JavaScript. Node was brand new, package management was brand new, ES6 wasn't even published yet, never mind usable. For the browser/DOM you likely used jquery because you couldn't use it directly, APIs like querySelector weren't available in a time when Chrome was less popular than IE6. You probably wrote "var that = this" a lot as most people didn't understand bind/apply. Modules were done by using a global object and sticking functions on that.
So I don't think JavaScript has yet earned being called boring on the same level as the others, even if the "days since last framework" days are over with React the winner and Vue/Angular the other survivors.
What does that have to do with its development status?
The RFC is just an extra easier way to do it.
If the OP is here, can I know where he faced the problem? Maybe the xommunity could have helped.
I would never consider React over Svelte. Except the community size all I see are disadvantages.
I faced the problem when trying to add layout styles to a component from the outside — basically, the parent should decide a component’s position/dimensions/etc.
FWIW, I don’t consider myself particularly good with web stuff. I’m just interested in graphics and I’ve beaten my head against it for long enough that I’ve figured out how to make some things :)
// Parent.svelte
<script>
import Child from "./Child.svelte"
</script>
<style>
.container :global(.child) {
color: red // your styles here
}
</style>
<div class="container">
<Child className="child" />
</div>
// Child.svelte
<script>
export let className
</script>
<h1 class={className}>I am styled by my parent</h1>I believe that the web has become a big pile of crap because of all those "modern" "frameworks". They tried solving problems no one had in advance. Back when I was in uni, in the second half of the 2000's, the web-part was actually enjoyable to work on. I'm really glad I ran away from that early on.
Can’t deny that isn’t progress!
JavaScript interpreters are present and used on more systems than any other language which makes your claim extremely inaccurate and even ignorant.
1. The horrid language that is javascript in it's core.
2. Everyone and their dog is a developer these days, and in 99% of all cases js developers without any fundamental understanding of memory management, data structures or algorithms(basically cs 101). For C, you need some fundamental understanding of all of those things for anything beyond "hello world". I'm willing to bet that if you ask 10000 js developers what the heap and stack are and how they work, 9998 of them would have never heard of those terms. And you'd probably have to add a few zeros before you get to someone who can answer that correctly.
As for the extensive usage - well yeah... All you need is a browser to interpret it. In the same way all you need to keep yourself warm in winter is to chop down a tree and set it on fire. That doesn't mean it's a wise idea to go out chopping trees in mass, does it? I lost the countless attempts to make a better language for the web and they were all killed off by the Stalinists at w3 and mozilla. As I said, react is a symptom of that stupidity, not the cause. I've said it before, I'll say it again: a good engineer and a good community are defined by their ability to say "OK, that was a stupid idea, let's go back to the drawing board". The web is in it's worst shape it has ever been. Coldfusion, flash and the ridiculous java applets were heaven compared to what we have now.
What the language designer accomplished is not simple. JS packaged functional expressivity and dynamic binding from Scheme and Smalltalk into a marketable form using Java/C syntax. That is not a corruption, it’s a design feature. Languages that use S-expressions, while pleasing to the purists, do not see much market traction. The best languages are the ones that balance functional idealism with pragmatism. It is true that the language has warts, but there is ultimately a reason that all the JS alternatives, such as Flash, Applets, Silverlight, VBScript and Pyodide failed.
I agree the web is worse now, but it’s not due to technical reasons. We have more options for web coding than ever before with AsmJS and Wasm, plus all the compile-to-javascript languages. You can choose to write using one of those ‘superior languages’ like with Scala.js, Elm, Elixir, Clojurescript, or any number of runtime translation layers like Brython or Skulpt, but people don’t choose to. Because that isn’t the problem. The problem is that businesses want less logic in the backend and don’t find sufficient benefit in optimization to prioritize it over feature work. That’s a disturbing business trend and hardly related to technical choice. For most operations, JS is blazingly fast due to the millions of hours that have gone into optimizing it.
Last, the people who are beginners and don’t understand the stack or heap, are not the ones running Webpack and writing (a significant amount of) React code. Those are distinctly different personas, and conflating them is insane. Either you are seasoned and can deal with the complexity that is the JS tooling infrastructure, or you are not and you probably aren’t using it as a result.
As for javascript being "blazingly fast": lol. Compared to what? calculating 924^42 with pen and paper? Yeah, in that respect it's fast. For anything beyond that it remains a paper plane. Wasm initially terrified me because it potentially opened the floodgates for all the "developers" to jump into what are real programming languages and make a mess out of them too. For the time being it's fine though: Jumping from
this.prop.element.parent.third_degree_cousin.grandParent.neighbors_dog.value.get_value().toInteger() = this.prop.element.parent.third_degree_cousin.grandParent.neighbors_dog.value.get_value().toInteger() + 1;
to
type ConnectionError = Box<dyn std::error::Error + Send + Sync + 'static>;
is not humanly possible... For now...
As far as large groups of people being wrong, that also applies to HN. The industry trend has been toward larger frontend components, and that’s not because of tyrannical engineers (since when do engineers have business power?). It’s just cheaper to create code on the frontend a lot of the time, especially if you have to weigh writing the code in JS versus e.g. Go with a properly formed GraphQL backend.
[1] https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
My point remains: javascript is the stupidest language ever made(including the esoteric languages) and it should have been scrapped a long time ago. I have 1000+ books on my shelves next to me and if I start describing the utter crap found in javascript, I'd have to write 10 times as much. Stupid type system, idiotic paradigms, no clear structure, shit standard library, inconsistent naming conventions even in the standard library alone, it's as compatible with lower level languages as olive oil and alcohol(ffi is absolute shit with outrageous overhead), slow, unpredictable, does not have a clear way to do basic stuff like deep cloning.
But you are right, it's cheaper to write an interface using javascript. But if cost saving is our top priority, there's yet another argument for scrapping it altogether: ncurses. 10 times faster to write, 10000 times better performance, runs on anything with a screen. I'd totally vote for dropping the current web in favor of console-based web.
Hardly an unpopular opinion here on beloved HN. I love you guys, but also am glad you don’t hold the reins to make this a reality. :-)
Yeah, for something like that you are going to need a lot of libraries and infrastructure to pull it off as a side project without heroic effort, so it makes sense to go with the most mature framework available.
Reasonable people aren't unqualified in their criticism of React. There are times and places for it, and this sounds like one of them. It is the over-use of React (and other SPA frameworks) that most reasonable people are criticizing.
The headline, a take on "Nobody ever got fired for choosing IBM" is interesting in it's own way, because that's the sentiment that leads to React being chosen for projects for which it is not appropriate.
Hey I got better ones:
- No one ever got arrested for choosing <technology-X>
- No one ever got convicted for choosing <technology-X>
- No one ever got put on a death row for choosing <technology-X>
I think the last one is what we should all use. It's a good standard to aspire to, a nice high bar, when we develop a technology.
I feel like this person would have been fired at some point, with or without React...
I can see both sides here - could be that the application actually justified a JS framework but nobody would listen - or it could be that a JS framework is totally overkill and would introduce unnecessary complexity.