78 comments

[ 4.1 ms ] story [ 147 ms ] thread
What's wrong with writing only JSX tho?
JSX is nice, but requires transpilation as JSX can’t be used by browsers directly. And as soon as you need a transpilation step you’ve opened yourself up to npm-hell with Babel, Uglify, Rollup/WebPack, etc - at which point people ask themselves why they’re even using JavsScript instead of TypeScript or going all-in on WASM.
Those tools do useful things. Forbidding developers to use arrow function syntax because you need to support IE11 isn't a winning formula.
Forbidding your developers from using arrow-functions such that you don’t need a JS build process can be justified.
Maybe a stupid question, but what kind of projects are ones where you don't need or want a build process?
Simple projects!

Projects where the client isn’t programmer-savvy and wants to make changes themselves and immediately upload them over FTP. Sites like self-hosted WordPress or hand-maintained static websites.

> Simple projects!

WP sites are far from simple. Maybe WordPress.com but definitely not the self host option. Not if you want anything other than a vanilla install.

> the client isn’t programmer-savvy > wants to make changes themselves and immediately upload them over FTP.

Why would you want a client who isn't savvy to make changes themself? Advocating for cowboy coding for end users is trolling... unless you're upselling a support package!? They can tweak things in the admin but I'd think long and hard before giving said client access to server files. Not to mention how easily end users mess things up by changing admin settings.

Having worked with such clients for 2 years, I gave up because at some point, the support burden was just too much!

Microsoft doesn't support IE11 anymore. You're probably safe to write modern JS unless you're in a very, very narrow niche.
That's not true https://docs.microsoft.com/en-us/lifecycle/faq/internet-expl...

And plenty of enterprises are still using it.

> And plenty of enterprises are still using it.

...but only as a back-up browser for those legacy internal web-applications. I’m sure all of them still install Chrome (or Chromium-Edge) for daily-browsing.

We sell into the NHS, and we still have high numbers of users on IE11 (and it's in our contract to support it). Chrome is definitely on the increase though.
> unless you're in a very, very narrow niche

you mean like every major bank, where something like 5% of their customers still use IE11?

The jump from javascript to typescript is trivial compared to the jump to some sort of framework built on wasm.
> JSX is nice, but requires transpilation as JSX can’t be used by browsers directly. And as soon as you need a transpilation step you’ve opened yourself up to npm-hell with Babel, Uglify, Rollup/WebPack, etc - at which point people ask themselves why they’re even using JavsScript instead of TypeScript

React is fine with TypeScript, too.

“If you are using React, you might as well also use TypeScript instead of just JS” may be true, but I don’t see how its a problem.

It's not part of Javascript, so you'll always need Babel (or similar transpiler) as a dependency and some kind of build step.

It's additional complexity when you could have solved the same issue by using better design on the API level.

Typescript transpiles JSX, which doesn't disprove your point at all, but it's worth mentioning.

I don't intend to ever write un-typed, naked javascript again if I don't have to.

Even scripting, ts-node is perfect for it.

And as far as complexity - I find typescript to be far better than webpack/babel in configuration and UX.

Nothing. It's a great innovation in web development and UI declaration to be more precise. I was skeptical for a while, but when started writing it it became natural real fast.
Here's the TODO example, which is at the bottom of the post:

https://codesandbox.io/s/competent-swartz-beoub?file=/src/To...

Not very readable

I'd argue it depends on what you're used to. Coming from React you could argue Reagent is not readable. Coming from Javascript you could argue that Objective-C is not readable. But it's more that you need a moment to get used to the new syntax.
The browser standards are behind. The img tag is wonky considering the various screen sizes and bandwidth variability today. Loading fonts is sketchy and weird. Anything to do with video is terrible. Anything to do with networking is terrible.

React and its ecosystems of libraries turn the browser in to something you can actually get stuff done with. Sure, it's a monster. But your codebase would be as well if you tried to fix all the janky crap in the modern web.

I don't want to program all my logic somewhere else. Front ends run on the client computer, I can keep one client's heavy computations separate from another client and it doesn't cost me anything. Fat front ends are the defence against expensive cloud providers or unstable self-hosted services.

> img tag is wonky considering the various screen sizes and bandwidth variability today.

The srcset attribute is well-established.

And please elaborate on the issues you’ve experienced with HTML5 video. Every platform supports AVC1 now, even Firefox.

> The srcset attribute is well-established.

on new browsers

> Every [new] platform supports AVC1 now, even Firefox.

React/Angular/Vue/etc. is the janky crap. The client side is MINE, stop wasting MY resources for your ease of development.

I say this as a developer that has to deal with "React apps" at work. As I user I can't stand the "modern web" where megabytes of Javascript are wasted turning a page load into a spinner that doesn't work half the time.

It's hard to take this seriously. Saying React is bloated because `create-react-app` pulls too many dependencies makes it seem like you don't understand what `create-react-app` is for. `create-react-app` is not a hello world, it's application scaffolding. Imagine if I said Ruby's hello world was 1 million lines because I had started with Rails. That is what is happening here.

Show me what longwood looks like when you have a large complex application with several re-usable components, then compare it to react. It's very easy to create "clean" minimal libraries that do nothing more than hello world. The complexity comes from building actual applications.

> It's hard to take this seriously.

Agreed. The premises are laughable.

It's other way around: create-react-app pulls too many dependencies because React is bloated.

They could have made React lighter and require no compilation. But instead they created a scaffold and fought complexity by adding more complexity.

React does not require compilation.
> They could have made React lighter and require no compilation.

React requires no compilation. (JSX requires compilation, but you can use React without JSX.)

> But instead they created a scaffold and fought complexity by adding more complexity.

CRA is a scaffold, but you don’t need to use CRA to use React.

> React requires no compilation. (JSX requires compilation, but you can use React without JSX.)

While true I don’t know that I’ve ever seen a non-didactic codebase that uses react but not jsx.

Can anyone point to any recognizable projects or products that do so?

You don't need to compile React, and compiling `jsx` is just a couple lines. Clearly there's something being missed here about the function of create-react-app. It's an application development environment. React itself is quite secondary to its purpose.
I'm not following your logic. React+ReactDom only has 3 dependencies, so I don't understand how that follows. How is React bloated because `create-react-app` gives you functionality to setup a PWA? If I don't care about PWAs, I don't need to use it, but `create-react-app` downloads it anyways.

The majority of the dependencies pulled in on create-react-app is from the `react-scripts` which helps entirely with scaffolding. Saying that React is bloated because the scaffolding generation tool downloads too much code sounds crazy.

(comment deleted)
> `create-react-app` is not a hello world, it's application scaffolding.

Somebody should've told that to pretty much every author of every React tutorial out there. They all start with `create-react-app` because it's "easier" this way.

> Imagine if I said Ruby's hello world was 1 million lines because I had started with Rails. That is what is happening here.

Incidentally, I remember visiting a code bootcamp a few years ago. Back then, they put people who never saw a line of code in their life in front of Sublime and showed them how to make web apps with Ruby on Rails. So this definitely happens, and the results are as expected.

Can anyone point me toward a light(er)weight boilerplate for a react/JSX app than create-react-app? I'm thinking just just package.json and webpack.config.json in a git repo that I can clone to start a new project. Something like this but for react: https://github.com/cferdinandi/build-tool-boilerplate.
Agreed on the create-react-app point. A hello world in React requires far less code than what CRA provides[0]. If they're gonna compare to create-react-app, then at least mention HMR.

The comparison of syntaxes also sounds a bit shallow. There are legitimate arguments for why one syntax might better than another (e.g. using a full blown templating language in order to allow the compiler to optimize more aggressively, like in the case of svelte and angular, vs using the parent language for ease of learning, like is the case for react). IMHO, the syntax argument in this article merely boils down to opinion (i.e. "X syntax is ugly, mine looks nicer") and ignores other alternatives (hyperscript being one big omission in this space).

As far as what React actually gets wrong, I think that are certainly things that can be criticized about it. The author of Crank.js does one such exposition quite eloquently IMHO[1]. The author of Solid.js has written at length about what performance could look like if we left various preconceptions and tech debt behind. Etc. Unfortunately, I feel that this article doesn't showcase nearly as much substance as some of these other libraries in the same space.

[0] https://reactjs.org/docs/hello-world.html

[1] https://crank.js.org/blog/introducing-crank

Using create-react-app is the solution to the problem of a sea of intertwined, tightly coupled, frequently breaking dependencies. Even with CRA there are still tons of frequent dependency problems.

Hello world may not require CRA, but not using CRA is often a huge mistake.

> Hello world may not require CRA, but not using CRA is often a huge mistake.

I'd like to learn more about bad times that have occurred due to failure to use CRA up front.

For example, having to help someone who was stuck for a day debugging a broken setup and it turns out they didn't know class properties are not JS
Writing no code and configuring nothing is better than writing code and configuring things.

That's more time you get to spend on your actual app.

Writing code and configuring things leads to responsibilities and technical debt. So rely on well known, free and easy solutions until you can't. This is the way.

Basically all problems with react end up being a day of debugging. The solutions are never a stack overflow question but are often the nth comment in a github bug report. on some obscure dependency your project only indirectly relies on. Deleting node-modules folder and reloading packages is a more-than-monthly occurrence. Manually tweaking package version pins, up and down, explicitly switching sub-dependencies out for newer ones that the maintainer hasn't updated yet, and discovering totally broken and totally replaced dependencies happens constantly. CRA saves you from many of the dependency headaches as it's all pre-pinned, but you still end up fighting all the same battles eventually.

I've never had more dependency hell or build problems with any platform I've used compared to react/npm, which includes Java, .NET, Python, and PHP.

How often do you run into problems like that? I've very rarely encountered anything like that with React, especially in the last two or three years. I don't use create-react-app and my package.json currently lists 88 dependencies.
Regardless of using CRA or not, would the adoption of a lockfile help in keeping your direct and indirect dependencies pinned to the same versions over time?
I experienced these issues with a lock file. Frankly, the dependency manager just isn't doing it's job well. It's job is to manage the dependencies so that I don't have to.
Serious question. Is there an alternative to create-react-app for SPAs? I know Next.js is the hottest framework right now but i'm only interested in client-side rendering
I'm happy with snowpack, it has a create-snowpack-app cli command with templates for react, svelte, etc.
> The syntax

I disagree. My team has written a medium size web app ( ~30 pages) without JSX and the API works pretty well. You get used to it if the whole project uses it (just like any API).

> create-react-app

I disagree. It is clearly intended as a quick start, people can customize or opt out in one command (and remove whatever they want).

It is very functional and engineers get a production ready layout and build system in < 1 minute.

It doesn't force you to use it, use it if you want.

--

Finally your example doesn't look much better or clearer than using the React API directly..

What was your motivation behind not using JSX?
The software environment was very locked for security reasons, no internet and etc.

Just felt it was simpler to not use JSX and to deploy with scp ;-)

In fact every dependency was manually downloaded and put on a vendored folder of the project. It was added as a dependency by adding a HTML tag.

All of it works surprisingly well..

> The software environment was very locked for security reasons, no internet and etc.

You mean the development environment you worked in or is this referring to production?

I can't imagine working without internet as a programmer.

> Just felt it was simpler to not use JSX and to deploy with scp ;-)

Tools like babel don't get shipped to production. They are part of the development build tools which gets stripped out. You can run a single build command on your laptop and SCP the result.

> In fact every dependency was manually downloaded and put on a vendored folder of the project. It was added as a dependency by adding a HTML tag.

You can lock the dependency versions so your production code would have the same code.

You can commit node modules along with your code.

You could use zero installs by yarn which compresses node modules to make it easier to push them to version control.

Why manual?

> You mean the development environment you worked in or is this referring to production?

I worked in. Is fairly normal to work without internet in some industries / environments (including my current one)

> Tools like babel don't get shipped to production. They are part of the development build tools which gets stripped out. You can run a single build command on your laptop and SCP the result.

I know. But I had no build environment.

And I know to your last reply too.

Interesting to know. Thanks for replying.

> Is fairly normal to work without internet in some industries / environments (including my current one)

Curious which ones?

Did you have to audit all the vendor code? If so, how much time was spent on that?

Do you think this kind of practices actually improve any security?

If there is no internet, how do you search for a solution to an immediate problem or look up documentation?

How is the testing culture like in these orgs?

> Curious which ones?

The Visual Effects industry in my case. Reason is unreleased content, for example, the new iPhone commercial or a new Marvel movie that hasn't been announced yet.

> Did you have to audit all the vendor code? If so, how much time was spent on that?

Yes, from days to weeks. It was a separate department.

> Do you think this kind of practices actually improve any security?

Yes, if your computers do not touch the internet and you do not have physical access to the device then you cannot easily leak content.

I am sure someone could take their phones outs and picture every screen of what they were working on.. but it is a bigger barrier.

> If there is no internet, how do you search for a solution to an immediate problem or look up documentation?

We had a separate computer (a windows box served through guacamole) that we could search things.

> How is the testing culture like in these orgs?

Nothing too different from others, the only real big difference is that you cannot reach to the internet from where you're developing software.

> If there is no internet, how do you search for a solution to an immediate problem or look up documentation?

Several DoE labs in the US were attacked around 2010. Jefferson Lab was cut off from the internet for several months (or maybe over a year?), and the only on-site access to the internet as a whole was a limited set of machines which weren't on the rest of the network. If you needed to look something up you'd go use one of those machines instead.

(comment deleted)
I haven't tried React without JSX, but I do find that switching over to the functional style interface I'm writing a lot less JSX. It's still there, and it's still the natural way to write the base-level components (divs and spans).

But at the next level up, it becomes really clear that <Foo x={1}/> is just syntactic sugar for Foo({x:1}), since Foo is just a function.

A lot of my code starts life as some chunk of a complicated render that gets refactored into a function. Then that function quickly becomes a React function component.

Next clean-sheet project I may try react without JSX. But I still rely heavily on newer ES features, so there may still be a cross-compile stage of the setup. While create-react-app is depressingly heavyweight, it is really fast and new JSX projects go up in a minute.

A lot of the code create-react-app generates is for the build/compile step. Hopefully leveraging things like native browser module loading, perhaps with polyfills for fallbacks, will become more commonplace for major frameworks in the future. Generally I think this post makes some very good points.
I think a good view rendering library should do just one thing well: Render the UI based on the app's state. It should not care where the state is, and most importantly it should not handle the state itself.

This is nice in theory, but in any non-trivial application, a huge amount of state exists just to support the view. It actually makes sense to keep the view stateful and it's counter-productive to further segregate view-specific state.

You can still keep large parts of your UI functional, but the idea that your whole UI should be a function from state to view seems misguided.

> React is not just a view rendering library anymore

I was felling like this too, but I found my balance using the Controller pattern, I only use hooks in controllers, and dispatch from controllers only, then I do not have logic in controllers, but I added some concepts of DDD having all the business logic separated, to the point I could change the whole ui framework (let's say material-ui by fluent-ui) and it wouldn't affect any controller, business logic or application types.

So with Typescript + Controller pattern + DDD concepts I'm quite happy with the separation of concerns.

This is how a route looks with Controller pattern.

        <Route exact path="/:username">
            <SignedInLayout backgroundType="paper">
                <ProfilePageController>
                {(props: ProfilePageProps) => (
                    <ProfilePage {...props} />
                )}
                </ProfilePageController>
            </SignedInLayout>
        </Route>
Any example repo or more detailed description of your approach (directory structure, building blocks, rules between these etc.) that you are willing to share? – We are discussing (and using) a very similar approach to yours so we are always looking for more input (especially on the DDD part).

In our case we have two widely different applications (the one being a "true" SPA with a single page and the other being a more route heavy application) and we try to converge on an approach that works for both (might not be reasonable, though).

This is what I love about react. There's so many ways to do things and I feel like every now and then someone finds a new way to optimize and reduce boilerplate even more. Nice job.
Hmm only a few points are valid in this criticism, I think.

- the jsx syntax helps hide massive nested functions. It would be a nightmare to manage any application without it.

- react has grown fat and does more stuff. Also it has a lot of foot guns with hooks.

- the create react app situation is absurd from this narrow point of view but when looked at from a project's perspective any team is going to choose it. The amount of features it offers out of the box would be insane to setup on our own.

- react has the biggest community right now and that will give a huge boost. Any good OSS library is not just about code and but also the community/ecosystem.

The criticism feels weak.

1. Javascript doesn't have the same semantics as dart and swift. Both of those languages provide features like named parameters which makes it much nicer to write composeable functional UI. The ecosystem is different. React chose to mimic html-like extension to hide their API because they were targeting web developers. Swift and flutter had to target mobile developers.

2. There are other options than create-react-app that you can use which aren't as bloated. You don't need create-react-app to write a react application. It's a combination of sensible defaults, support for older browsers, polyfills and much more. You can use react as a library by installing it through npm without other packages.

3. Any library will have an ecosystem around it eventually if it gets popular. You can't stop defaults, conventions and patterns from emerging as a result of learning and figuring out the pain points.

The rest is author describing his project.

As is often the case with these discussions, there's seldom an absolute right or wrong, but a "so what" relative to a goal.

My impression of the point of React is that it allows you to quickly write web apps which are reasonably structured/maintainable, performant and not flaky. My recent (non professional experience) with React seems to confirm that it indeed achieves that.

It was indeed originally weird to me to do react-create-app and have all the magic happen behind the scenes, but again, the goal is to get you up and running fast and it achieves that. You can whittle it down later or start from scratch if you want.

More importantly, writing in react doesn't (seem) to make you hate yourself. I was able to structure my app so that it's logical and changes to components can be made in isolation - that's already huge. More important is the question of "how much code am I forced to write that I don't want to write" - the answer is not much. The most annoying thing I find is having to kinda manually handle changes to form fields but otherwise it's pretty reasonable. So it feels like it succeeds on its goals.

Once we get to esoteric things like "JSX is bad" or "Hooks are dirty" -- ok? I guess I am not sophisticated enough to understand why that is so it doesn't bother me, and again, React seems to strive more for practicality than ideological purity so whatever that tradeoff is, is likely right.

Full disclosure - I am not a professional web developer. Last time I made money making websites was 2003, though I did recently build https://playdurak.gq/ with only JS and CSS on the front-end, and currently am learning react as I build a webapp for my own purposes.

Edit: I guess if anyone actually wants to play the Durak game, here are the rules. https://gathertogethergames.com/durak I built it for my friends and I who already knew them.

I agree with a lot of this criticism. Babel is a very gnarly beast and while it once served a very critical purpose, it's time to start sunsetting it again now that most browsers support modern JS.

As another alternative to React that's very lightweight and doesn't need much tooling, checkout Mithril[1] which is my go to for most personal projects. If you happen to really like JSX, you can use it with Mithril with ease, but you can avoid JSX entirely and use Mithril's very convenient built in alternative.

[1]: https://mithril.js.org/

How about just what a giant pain mixing hooks and older code is? So far I've only used react with a side project where one developer knew and loved hooks and the others didn't. The number of difficult to understand integration errors related to hooks and other (older) react techniques was impressive.
Great points. I agree with them completely.

There are a lot we can do though, without leaving the React ecosystem. (Which you probably shouldn't because of React's popularity)

1. Ugliness of createElement API and JSX:

There is always Hyperscript: github.com/ohanhi/hyperscript-helpers.

2. CRA:

CRA is a monstrosity all right, which becomes more obvious when one has the misfortune of ejecting it. But it's not required at all. One can easily get away with a ~100 line Webpack config or with Parcel for simple scenarios. This is what is already happening, a lot of experienced users are avoiding CRA.

3. Hooks, fibers, suspense:

We don't have to use them. We have HOCs for years which are simply the React version of the venerable decorator pattern so actually no one needs a silly abstraction such as hooks. And I don't think fibers & suspense are features that the average React user needs to use at all. Just forget about them. Until you really really need them, but you'll know when this happens.

4. Global state and black magic:

Because of Redux' popularity, at some point a lot of developers started to believe that we should shift as much state as possible to a global data store. This resulted in a lot of unnecessary complication, pain and suffering in a lot of codebases. But of course this mindset is not to be blamed on Redux nor React itself. It is just the result of a poor understanding of state management, patterns established around this poor understanding, and copy paste culture. Global state is definitely not bad per se and not really threatening when it's experienced hands working on it.

It's probably a bad idea to say "X is wrong" when you haven't done enough market research.

OP seems to think he's invented some completely new way of doing things but i wonder if he's seen things like:

- Mithril: https://mithril.js.org/

- Cell: https://github.com/intercellular/cell

- Hyperapp: https://github.com/jorgebucaran/hyperapp

and so on. I dislike React more than anyone else for its bloated way of doing things, but there are always legitimate reasons why people use things they use. The announcement would have been more productive if he just shared the project in a humble manner.

My first modern framework was VueJS, but everyone was urging me to learn React or Angular. I have too many projects on my plate to learn the last two now that I'm deep into Vue, but I'd really like to hear how the three stack up. The reviews I've seen online aren't particular in-depth.

Is this article a case of "every framework has warts", or are this issues really that bad?

Before JSX, you'd have to find a templating library like Mustache or Handlebars. You'd have to keep your templates somewhere (the usual convention was a script tag), read them in, compile them, etc.
I used to use React a few years ago for all my projects, and a friend recommended I try out Vue, and I rewrote my massive project in less than a quarter of the time. And in the past year I discovered Svelte/Sapper, and I rewrote my app in even less time than that.

I guess my real point is React is great, but not for all use cases, and I've come to really love using Sapper for my purposes (small, fast API-driven MVP web apps built by a single person team)

> I used to use React a few years ago for all my projects, and a friend recommended I try out Vue, and I rewrote my massive project in less than a quarter of the time. And in the past year I discovered Svelte/Sapper, and I rewrote my app in even less time than that.

Shouldn’t rewrites (other than perhaps to something with both an radically different and less powerful basic paradigm) generally take a lot less time than original creation?

I mean, it doesn’t sound like this is saying much.

Alternative anecdata: Our team went through some changes and for some odd (inexplicable) reasons we ended up switching from React to Vue. Only one person seems to be happy about the switch and at this point we can't go back very easily. There's about 4 of us that are just kinda barely getting by with vue as we we're pretty proficient React devs. ¯\_(ツ)_/¯

Writing a new interface feels like days instead of hours for us.

Hey J2EE had a lot of believers for a long time too.

Don't feel too bad about it. The industry does this stuff every decade or so...