Moving on from React, a year later

yakshaving_jgt | 296 points

I was worried that an application I was building in Django, with a frontend built with Bootstrap and some LIGHT jquery was making me look like an old curmudgeon but the part about testability of the frontend really resonated with me. It was MUCH easier to structure everything as pytest unit tests and completely rely on Django for all the business logic rather than trying to put state in the frontend and deal with synchronizing states between FIVE distinct systems (remote devices, the Django application, the database, an event stream, AND the front end).

I recognize that I'm not hip or with it, because I really fell out of front end development at the peak of jQuery where it was mostly about fixing browser incompatibilities, but it's nice to see that maybe it went too far in the other direction and we're overdue for a bit of a swing back towards server side.

sc68cal | 5 months ago

> Let’s assume that making a JS change costs twice as much time a Ruby change, which I think is being generous to JS.

Everyone's mileage varies, of course, but this is quite the assumption. It feels like a lack of familiarity/comfort with the frontend or poor tooling.

With typescript and a basic UI library like MUI, this really shouldn't be the case for UI changes. If you're using raw JS and manipulating the DOM, maybe?

tyre | 5 months ago

HN is not real world, just like how Reddit is not real world.

I am a FE with 10 years of experience, and has tried, and tried really really hard and multiple attempts to make HTMX works well.

Doesn’t work. UX is much worse, code discoverability is much worse, slower to code in, everything is messier than just plain React SPA with JSON data. Terrible, terrible DX and UX.

Seriously, there is a reason why despite all the rage in going back to multi page Django/Rails app, very very few people actually take it seriously. You just don’t hear the negativity because most folks just tried it, saw that it is worse, and moved on without writing a blog post.

htmxsucks | 5 months ago

FYI - There's some neat ways you can embed React components inside Rails templates. Basically - embed the props in a template-managed `script` tag, and use Stimulus to mount the react code, passing in the props read from the DOM. Now your React is pure state-to-view, no need to synchronize anything, - it's really just a handful of React components instead of a full React app.

That said, AFAICT, there's just two advantages:

1. Those annoying little UX doohickeys that actually DO want that level of interactivity

2. You can use any of the vast library of existing React components (for me, that's been react_big_calendar)

As a bonus (and, why I rolled my own, since `react_on_rails` doesn't support these), and with a bit of tweaking:

1. It plays nicely with Turbo. I can use Turbo to update my React props and it just... works.

2. You can embed a template as a child of the React component.

2a. This also plays nice with Turbo.

It sounds a little screwy, but so far it's working well, and it feels like it lets me use the right tool for the right job - aka, Rails for everything except the stuff with extremely high interactivity.

RangerScience | 5 months ago

People in the comments talk all about their favorite pet tech stacks with only a single purpose: how long it takes them to write code. In front end logic that typically means putting text on screen or interactions.

Years ago I decided to not worry about those concerns and it turns out those concerns are irrelevant. Writing content, really all front end logic, is as fast as you can type on a keyboard irrespective of your tech stack. Just about everything else is over engineered insanity. That was even true back in the IE7/8 days.

It became apparent to me the only thing that mattered is time to refactor. The larger the application is the more true that becomes. The things that help with that the most are type annotations on everything, high execution performance, and fast test automation. Everything else became a distraction or noise that got in the way. The application does what it promises or its defective. It can be modified quickly or good ideas are abandoned for risks or costs.

So I don’t worry about tech stacks and spend too much energy on execution speed.

austin-cheney | 5 months ago

Server rendered HTML is all well and good until you want to add native apps or a first class API layer. At that point, it makes more sense to have the web be just another client and move as much business logic into the API layer as possible.

ec109685 | 5 months ago

A friend mentioned this made the front page. I'll try to answer any questions on our approach at Scholarly. Thanks for reading!

kellysutton | 5 months ago

I think the idea of "sprinkling" JavaScript into your server-rendered HTML is a good one. However, I think that Stimulus is terrible.

1. There isn't a good way to test it. There is nothing in the docs about how to test it.

2. Keeping state in the DOM is dangerous

3. Messaging between Stimulus controllers is painful

4. They disconnect parameters from functions. The functions have to scan through the DOM to find what they need which I think is fundamentally weird

5. Reusability is rare

6. It doesn't try to play nice with the larger JavaScript ecosystem.

I personally prefer Vue.

phaedryx | 5 months ago

I think the key takeaway of the article is:

> Code is not an asset, it’s a liability.

> What is the least amount of code we can write and maintain to deliver value to customers?

regardless of HTMX/Bootstrap/react, the simpler the better.

est | 5 months ago

Watching Meta rewrite Messenger twice without success was enough for me to never touch React for any large project, especially after that botched e2ee chat rollout.

overstay8930 | 5 months ago

The only UI framework I’ve ever used that I didn’t absolute hate is DearImGui. I realize it doesn’t produce polished, professional looking UIs. But my god is it the only thing that doesn’t suck.

JavaScript and ReactJS are at least 10 times less efficient to write than C++ Dear ImGui. That’s so crazy.

forrestthewoods | 5 months ago

> but I think the “fat client” era JS-heavy frontends is on its way out

Look, you might be right! I still think it’s not the right tool for all situations. But this has been said over and over for at least ~7 maybe 8 years for what I can remember and it’s yet to be true, for better or worse. We’ll see though!

girvo | 5 months ago

The older I get, the more I find myself gravitating toward building with Express.js, using front-end HTML with a touch of Alpine.js—and that covers 99% of my use cases. React is mostly an overkill.

senti_sentient | 5 months ago

> p75 at 350ms

Is this really that impressive if you're prefetching? Surely a cached response is <50ms always. What's the prefetch cache hit rate?

If it's anything like remix/react router prefetch caching, it's also useless on mobile. Depending on your target market, that's a huge difference

willsmith72 | 5 months ago

Went all in on the BALL stack (bootstrap, alpine.js, laravel livewire) and couldn't be happier

elchief | 5 months ago

On the contrary, I would say the end user's device has never been more powerful and it will continue to get better.

In real world we are supposed to use that resource(client side compute/storage) to balance the server side and client side processing, not just for performance but for optimal user experience.

scottydelta | 5 months ago

I think this varies wildly on the type of app you're building. If you are building something like CRUD interfaces obviously a server side focus is very viable and useful since you don't have to have double state management. I am thinking apps like ecommerce, banking or management software.

But if you're building a very client heavy application that does something like Photo editing, CAD, video editing etc I have a hard time seeing a server side generated content to be successful because you need a lot of client side state no matter what.

For example, I have done a lot with maps and it's not possible AFAIK to render the canvas on the server since it's a browser only api. Also I don't really see the benefit since it takes too much computational power to generate graphical things on the server.

staticelf | 5 months ago

> One of the arguments for a SPA is that it provides a more reactive customer experience. I think that’s mostly debunked at this point

That's not true. You absolutely can make edge applications faster than anything running server-side. A great example is Linear, it can switch between issues within 100ms (it even supports hjkl keys for navigation!).

But this requires you to be EXTREMELY careful. In case of Linear, they're using a sync engine to replicate the data onto the client side, rather than doing the request/response model.

cyberax | 5 months ago

Never thought about SSR making your code more testable. That sounds pretty appealing.

Also, does p50 mean median?

stevage | 5 months ago

I'm just hoping 2025 will be the year of Vue or Svelte. Maddening that people are still picking React over much superior frameworks like those two

sensanaty | 5 months ago

If you don't over complicate it, React apps are very simple. Emphasis on the very. The opposite is also correct. If you DO over complicate it, React apps are extremely complicated.

Also, the SPA model works great for some apps and badly for others. This blanket ruling of "do x and not y because x worked for us and y didn't" is just bad advice.

harel | 5 months ago

I removed all of our React and replaced it with Web Components, and I'm not missing anything.

I'm sticking to cached static resources, and just sending data over. Not rendering from the server, but not writing single-page apps, either. The more you render from the server, the larger your caches end up. Not doing that for HTML.

Just HTML, CSS, and JavaScript. No tooling. No building. Web Components and fetch(). No frameworks on the client-side. Express still on the server.

I'm trying to optimize for not swapping out dependencies on a several year scale, and it's working out pretty well so far. I removed React because they're not interested in UMD builds anymore, and I'm not going to jump through hoops to make it work on my end, either.

andrewmcwatters | 5 months ago

It's interesting to hear varying takes on this.

But my personal belief is that web apps are moving towards static sites that are cache-friendly and offline-ready. This for couple of reasons, first is easy integration with CDN. Second is easy integration with webviews for mobile apps.

And easiest way to implement offlineness so far has been through a state management library. Doesn't mean that doing what the article suggests, moving logic to server, is impossible but it's quite a pain. Much easier is to move logic to client and handling it there.

Moreover, the fact there's so many UI components and libraries available for React and so forth, makes developing much faster. Depends on the developer, of course (and I personally prefer Svelte), but is a rather big advantage if you are doing anything complex in UI.

tekkk | 5 months ago

Im using RTK Query with React with apps where i dont control the API and just consume the JSON.

The problem with RTK Query is the strong reliance on the internal cache, which is often in the way, since i need the updated data from the server most of the time, but otherwise it works quite well.

For apps where i control the backend (mostly PHP with Laravel or Symfony), im using Inertia now, which enables me to directly access the entity/model data in the React code, without any API necessary.

This works really well and reduces the React code to the minumim, UI based stuff, where it shines.

There is a Stimulus/Turbo plugin for Symfony as well, but Im not sure if this technology isnt too niche and unproven yet, in contrast with React, which has been around a long time, has tons of docs, and also loads of devs with experience on the market.

tacker2000 | 5 months ago

Its somewhat amusing to me that in 2025, you can still find comments equating React to hype. I've been using React professionally for 10 years. Can we at least agree its not a new, hyped technology?

IMHO there's exactly two factors when it comes to having success and efficiency with established tech like React or Rails. One is familiarity, the more experience you have, the more you know it, the more you like it, the better you are going to be with it. The other is restraint. The less custom EVERYTHING you make, the easier it will be to maintain and change. If you lack one or god forbid both, you are going to have a bad time. If you have both, probably anything that's not actually bleeding edge will work out well for you.

cloverich | 5 months ago

I was apprehensive at first, but it seems like it works for them and they make some interesting points.

abc-1 | 5 months ago

I got so sick of having to deal with thousands of dependencies with a React project, I manually implemented JSX to string components (e.g. building with ESBuild then writing the createElement and fragment functions as my own package, which would return a string to render server side), added Alpine.js, and it's just as, if not more productive than standard React.

So many fewer packages to deal with (especially if you want to SSR your app), and my site is way faster. And I get to use JSX which is my favorite templating engine and requires little porting from my React app.

I suggest people really take a look at Alpine.js, you can do everything in it as you can with React and it's a significantly smaller, simpler package that runs right in your browser.

65 | 5 months ago

> Many interactions are not possible without JavaScript, but that doesn’t mean we should look to write more than we have to.

PREACH. And many site actions can be handle server-side without degrading the user experience.

insane_dreamer | 5 months ago
[deleted]
| 5 months ago

I have a 6k monitor. why are you embedding a 1400 px image I can view fine into a little 640px column which makes it hard to read?

henning | 5 months ago

I don't know React very well but I used Angular in a large project and it was completely baffling to me how overly complex it was. In certain areas of the application it felt like it was completely unpredictable what value the state was going to be.

I sometimes long for the simplicity of something like Windows Forms.

martijn_himself | 5 months ago

By that chart, it looks like you moved that code to the server. Which is fine - I prefer the back end these days too - much easier to monitor and reason about. Especially for a cloudy app. Not so great if you are going for the offline-available featureset though.

sharpesttool | 5 months ago

I’m building an application with much the same stack and it’s refreshingly easier for a one man shop to use the tools he describes.

I used React at my previous job and it feels like a nightmare thinking about it again. Hotwire is a simpler approach that pays off.

xutopia | 5 months ago

Full page navigation is the web's super power and what makes it scale.

In my view one of the first things you should be doing when working on a web-app is to work out where you can place them, rather than trying to avoid.

DrScientist | 5 months ago

Where did we go wrong? May be we need something different from HTML. A new spec to render user experience. Possibly same spec for Browser & Native apps across all devices.

the_arun | 5 months ago

Really hope there are more in Rails 8.1 and 9.0. More extracted tools, more defaults, higher performance. I mean we really should be aiming at p99 350ms.

ksec | 5 months ago

But, was it JS alone or the rendering of JS and CSS in the browser container???

For context, the Dart Flutter stack started out with the concept to make web apps faster....

fredgrott | 5 months ago

I think you could achieve the same with Next.js's RSC (React Server Components).

literalat | 5 months ago

Do you also have a native app? How do you plan on using your current setup with Swift?

arvindrajnaidu | 5 months ago
[deleted]
| 5 months ago

From slop to even bigger slop, congrats!

sonicgear1 | 5 months ago
[deleted]
| 5 months ago

We're four years into a journey that shouldn't have worked but did. I have a lot of experience with mostly server side JVM stuff and a little bit of frontend. Before 2020 that was mostly standard stuff including a largish javascript /typescript project and a bit of react.

In 2020 I took over the skeleton team of a startup. My main (junior) developer had a bit of Android and Kotlin experience; not a lot. We had no resources to get more developers. I was focusing on building the backend, which barely existed at that time so it was all new code. I picked spring boot and Kotlin for that.

We needed web and IOS apps in addition to Android and the Android app (the only thing that had been built) was a bit of a mess and honestly there wasn't much worth keeping. And with just one developer it was clear the replacement was going to be a web app. The obvious thing would have been to potty train my junior developer on react/typescript and hope that after a few months he would become a bit productive.

Instead I took a wild bet on kotlin-js. I honestly did not expect that would work. But it did. We did a brief research spike. Very successful. My junior developer did all the work. And we continued from there. I always had the plan to at some point just parachute in more developers and re-do it properly. But that never happened and nor is it needed.

Fast forward a few years, we still work with kotlin-js. Over the last four years that became more stable and better supported. It's great. It's a four year old UI code base and we're making lots of changes with confidence all the time. Kind of the gold standard for a good code base. It sure has its issues but it's under control.

Mostly I can't tell the difference whether I'm working on server or frontend code. It's all Kotlin. Kotlin multiplatform ensures we can reuse a lot of code on both. So the default place for code to go is in some multiplatform library. Which then ends up being used on both server and client.

We use a small, obscure UI framework for kotlin-js called fritz2. It emulates a lot of what react does but in a Kotlin friendly way (strongly typed, co-routines). We use tailwind for styling (after some adventures with other stuff) and are slowly converging on maybe adding daisyui to that mix (which is nice).

A lot of stuff in browsers is of course asynchronous and as it turns out, Kotlin's co-routines are awesome for that stuff. We have a lot of long running or recurring stuff happening in background co-routines. Handlers are suspend functions, etc. Integrating existing javascript frameworks is fairly straightforward. We have a few of those. Things like maplibre and a few other things.

The point here is that frontend code doesn't have to be Javascript and it doesn't have to be miserable like many Javascript projects become. Where you run your code and what language you pick for that are two independent choices. And if you have proper well designed code, it should be testable. Just because it runs in a browser is no good reason for that to stop being true.

I wouldn't recommend my choices four years ago. But at this point browsers run a lot more than just Javascript. Getting stuck with that stuff is a choice, not a necessity.

jillesvangurp | 5 months ago

Angular apologist here. Learning curve is somewhat steep but I can be immediately productive in it and testing is built into the framework as a first-class citizen. Routing, debugging, state management, SSR, it’s all there. I like the separation of controllers, HTML, spec tests, and CSS because it allows the developer to reason about these separately. DX is damn good.

In fact I recently whipped up a front-end UI in a few days using the BAEL stack (Bootstrap Angular Electron). You still need the data layer of course, but this would be true of any UI framework unless you want to go full monolith like Rails (which I still fully believe is a superb solution).

And having done Rails, React, Angular, and a mishmash of other frameworks, libraries, and architectures, I can say that a “pure” Rails app out of the box is impressively good for most use cases, especially now with Turbo.

temporallobe | 5 months ago
[deleted]
| 5 months ago

Unfortunately for many of the HTMX/Turbo people, they did right to identify the problem but they have the wrong solution.

The way to alleviate those issues is not to bloat the frontend with things that shouldn't be in it nor is it to fragment the code base with never ending "sprinkle" of JS.

The best solution is something like Gleam's Lustre, where you use the right tool for the job, while keeping a coherent code base:

https://blog.nestful.app/p/gleams-lustre-is-frontend-develop...

oDot | 5 months ago

Maybe it’s the changing interest rates or political winds, but I think the “fat client” era JS-heavy frontends is on its way out.

This is just not going to be true. It’s an AI world and we need to funnel so much high velocity text and dynamic UIs to provide a high fidelity experience.

Investing in static server rendered pages is just a surrender, the long surrender that people desperately seek from the onslaught of JavaScript.

But it won’t happen, it will either be JS or another language, but server side pages is the wrong bet.

bloomingkales | 5 months ago