This article has been re-written for over a decade.
The so-called "complexity" is just a list of tools that each solve a specific problem.
Tooling isn't the problem: The complexity is inherent to modern web development. You see similar "hidden" complexity in other frameworks like ASP.NET, and GUI desktop frameworks as well.
If you're using Rails as an API backend with React handling the frontend, it's almost a completely different application architecture than a traditional Rails monolith. So the list of tools (Vite, React, Prettier, etc..) is almost for a completely different problem (again, unless you use Rails for FE; if you want to use Rails for Frontend, use Rails for Frontend; not a fan of the mash-up at all.)
The real issue is learning methodology:
A lot of developers today start their careers with frameworks (point 4) before learning the fundamentals of the web (points 1-3).
HTML for markup.
CSS for styling.
Learning server-side logic (e.g.: <forms> can POST and can return a completely different page at the same URL) and databases for dynamic content.
Then, JavaScript for interactivity.
Embrace the tools: Each tool on the list (Vite, Tailwind, etc.) exists for a reason, and they're all necessary for a modern web application.
Saying there are "too many" is an amateur take on the reality of the ecosystem.
Complexity is not inherent to web development. If anything it is now possible to get more done with less.
Hotwire is sort of vanilla rails and it enables you to create very modern experiences with content live updating through web sockets and it is basically a one liner to setup.
The de facto way to deliver JS in rails has also become far simpler through import maps. There is no build step for that. Tailwind support is a flag away when generating a new rails app and is super simple.
Deploying has even become simpler through kamal.
So no, complexity is not inherent to web development and the article is wrong in marking Hotwire as “complexity”. If anything it makes it simpler.
I agree with your point about learning, but learning shouldn’t be about learning more tech. The learning should be how to get more done with less. Anyone can use 20 different programming languages and servers, the skill lies in using 4 of them to do the same and outperform a thousand person team with just 3 devs.
>> "Complexity is not inherent to web development"
>> "Hotwire is sort of vanilla rails and it enables you to create very modern experiences with content live updating through web sockets and it is basically a one liner to setup."
My point was that web development isn't complex, but the core is simple; but modern web development is.
Your "Hotwire is sort of vanilla rails" statement is a perfect example.
What you claim to be simple, is a big list of tooling, web-sockets included, integrated together. The end result is using it might be a "one-liner", but that doesn't mean it's simple. And that's OKAY. Because simplicity should be the standard; and adding things, like sockets for live updates, should be something you explicitly enable (with modern web-apis, its definitely simpler than it used to be, but that doesn't mean its simple)
This really is different. Hotwire is simple. You can read through the library's codebase and understand what it's doing fairly easily, and then when working with it the flow is straightforward. Good luck doing that with React
“Just rendering a component” takes thousands of nested function calls, covering a million lines of code; it’s not possible for a person to read or understand the whole process unless they dedicate months to it.
Sure it adds complexity, but isn't that what abstractions are for? We are talking about grokking how data flows in _a web app in Rails_. I wouldn't think usual workflow requires going into actual inner workings of React :p
Once you give up any hope of understanding the inner workings of the frameworks you are using, you're no longer a programmer, you're a cargo cultist. Now compound this a dozen levels deep, with systems piled on systems built by people who don't understand the other systems they are building on top of, and you have the current mess.
Well React doesn't come by itself. You need a router, probably some way of managing shared state, bundling, compiling your TypeScript, and 7 other libraries
The more stuff you add on the harder everything is to understand, and the less stable your app becomes until suddenly you need specialists for every piece just to keep things chugging forward. Everything needs greasing and maintenance over time..
..and then in 4 years the React team decides "oh you know what the way Svelte is doing things is actually way better.. we'll need a re-write to integrate their ideas". Now what?
"that wouldn't happen! so many businesses depend on React!".. uh they have no obligation to make things compatible with whatever you've built. They're not working for you. What happened with AngularJS? Vue 2?
Hotwire is easy to understand (React "just renders it" is a massive oversimplification)
If Hotwire rewrites? I create a private fork and continue on. Who cares
If I want to tweak how Hotwire works cause it'll benefit my app specifically? I do it myself
I'm not against adding complexity.. but if you care at all about longevity and long-term productivity then adding React really needs a tonne more consideration than it gets
I think we fundamentally agree that we want to be careful about adding complexity to a project. Funnily enough there have been many times where I really thought Hotwire equivalent would have cut down a lot of complexity. I've also actively looked at web components at work and for hobby projects to see if we could make/keep things simpler.
But maybe I'm biased because I've been working with React for a long time, I don't find it too daunting to manage dev tools around React. When React was young, I remember that there were _a lot_ of ecosystem churn but now it's more-or-less settled and I don't think it's too bad.
I don't know how Hotwire works that well as most of my experience is around Elixir's LiveView, but at least for LiveView, there is also quite a bit going on under the hood to make it performant for large lists and to handle error states gracefully. And I (maybe incorrectly) assume Hotwire is similar, so I feel like it may not be not as simple as you say. (Edit: it is simpler than React though!)
It also doesn't need to be all or nothing. I've become a big fan of progressive enhancement or an islands approach. Default to SSR and scale it up as needed
I don't think a typical React rendering call is even 100 calls deep. React itself adds maybe a dozen frames. Your components could be complicated, but likely they don't add more than another dozen or two. React is pretty efficient if you hold it right, and use for its intended purpose, that is, large and complex interactive UIs.
And also, that with React you are not only buying into React, but also a JavaScript dependency manager/package manager. Be it NPM, or any other. Installing JS package itself already comes with its own problems. And then probably people buy into more stuff to install through that package manager. Some component library and a "router" here, some material style and a little library to wrap the root node with some styling provider or what it is called there, ... before you know it, a typical FE dev will have turned your stack into 80% React and related dependencies and the maintenance on that will continue to grow, as new features "can be solved sooo easily, by just adding another dependency" from the NPM/React world.
This does not change if you write pure Javascript that directly mutates DOM without calling any intermediate functions.
Given the speed of rendering that browsers achieve, I would say that their call stack during this is highly optimized. I don't see OS doing much at all besides sending the drawing buffers to the GPU.
When you write "The complexity is inherent to modern web development" you are describing the problem, not a requirement. When you are pulling in a thousand npm packages just to make a simple transactional website that is a wrapper over a database and a few SQL queries, you're doing something wrong.
I think the pushback isn't so much against the existence of the tools per se, more against the pervasive idea that everyone needs them.
When every other learning resource is titled something like "Ten reasons you need to be using the MONGOOSE stack right NOW!", it's no wonder we've got people trying to shove redis into their baking blogs.
Matter of fact is, the average website would be fine without a "stack" of any kind, but no YouTuber sells sponsorships telling their viewers that. Ergo, many junior devs genuinely don't know that.
While I agree that people should be primarily learning the core tech, it's a difficult message to deliver amongst the cacophony of corporations trying to promote their services.
As an example of this, I had to build a management interface for the backend of the project I was alluding to above; itself a web app in its own right. Written entirely in Python, with HTML templates, CSS and JS and a bit of SQL with no "web frameworks", no other dependencies except nginx to proxy requests to it. Easy and quick to develop (a couple of days), and very unlikely to suffer from software rot, unlike a web-framework based system - Python (at least since the Python 3 debacle) has excellent backward compatibility, and basic HTML, CSS and JS likewise.
What it did lack, though, were fancy widgets and other decorative bells and whistles. But is it worth the cost of pulling in the vast overhead of "modern" frameworks, and their resulting complexity and maintenance problems, just to have those?
And also in jobs many if not most places you go will already have made decisions about how they do web stuff and once more juniors are being given the impression, that this is how things are done "professionally", while actually that is no more professional than any experienced hobbyist making their website and often worse in aspects such as accessibility (need to run JS and often breaking browser functionality like the back button), complexity (maintaining the interplay of all those tools and libraries), maintainability (updating your dependencies frequently), feedback cycle (complex build pipeline, instead of just delivering HTML, CSS and perhaps a sprinkle of JS).
This is why I don't want to do much frontend in businesses, where there is a separate dedicated FE team. It seems to me, that traditional fullstack devs, not FE devs who want to do backend stuff in NodeJS, but devs who happen to have learned web standards like HTML, CSS, and JS along the way, not as a "one ring to rule them all", make better websites. Maybe not as fancy optically, but often more responsive, and better in the listed aspects. But this may be bias, because such websites are far and few between these days.
As someone who’s kind of a newbie in rails, but with 10 years of experience in other languages…
It sounds ok to adapt tools if needed (won’t get into whether tools are actually needed, let’s assume they are).
But Rails is supposed to be a giant, everything and the kitchen sink framework bringing everything from an ORM through its own console to scaffolding code generation.
If adding tools to the setup is needed, isn’t then rails the thing to reconsider? Something more modular could probably work better.
Just reading “vanilla Rails” sounds like a red flag. How can that behemoth be considered vanilla?
All the tools on the article are about client-side rendering and operations.
It's ok if Rails decided to have opinions on client-side rendering and operations now, but it's far from expected. And it would alienate some users.
Instead, the article's conclusion is the correct one. You don't need to mess with complex client-side and ops tools if you don't want to. You can build many things perfectly well without them.
On one hand, I hear you, because Rails has focused on the server side.
On the other hand, Rails has had client-side opinions basically forever; when I started using Rails during the 2.x days in like, 2009, there were helpers that injected JavaScript to make forms better, Rails 3.1 included the asset pipeline, an attempt to compete with webpack, in 2011. Even the current generation of these things has been around for a long time, Hotwire is four years old at this point.
I mean, I think the problem with SPA-like client-side approaches are that there aren't any that have felt _good_ with Rails, let alone great.
Absolutely true that not every app needs to be a SPA from day one, but I do with there were a few more common solutions for "hybrid" apps, which use some pages as a SPA. That said, it's not that bad once you've got it setup. I like that Rails offers a solution like import maps, but I do also wish there were better core functionality for using some kind of package manager.
Like the redis analogy: Whether or not you need Redis, there are good defaults and very good 'third party' solutions for background jobs (or caching). You don't even need Redis is many cases, but it's easy to grow into.
Some of these extra tools are added because someone wants to display "a blog post" using React and so they think they need all those extra tools for FE.
If there is no need for the level of reactivity that is on the level of facebook style then everything provided by a simple rails new is enough.
But I would say that you kinda need to think about the UX with simplicity in mind or else everything becomes a blog with React because everything can be forced to look like it needs to be reactive and do a lot of unnecessary stuff.
'vanilla rails' is really a bunch of other tech bundled together. including much of it that is rendered using other technologies. hotwire? javascript and websockets. The thing that always gets me about Rails (and I am a decades long fan of it,) is that when they upgrade major versions, all of the tooling that comes bundled in the box changes. Sure rails 1.0 didn't have websockets bundled in but it did indeed come built on Prototype.js, which if you still have in a rails 8 project probably gets a lot of laughs. There's a lot more to 'staying current' in a long lived rails app than just upgrading the gems.
>'vanilla rails' is really a bunch of other tech bundled together.
That was roughly my point - unless there's something wrong in my mental model, a Rails user is someone who trusts Rails to get them a sane and consistent bundled pack of tools so they can skip the choice and get to work. If one is going to choose a different set of tooling later on, that seems to defeat the point of using Rails in the first place.
I was not judging the framework itself, for the record. Just saying that if you go for it, going "vanilla" seems like the only sensible choice.
>when they upgrade major versions, all of the tooling that comes bundled in the box changes.
I think the point of the article is that it's likely you didn't need a "modern web application" in the first place, because vanilla Rails would work fine. But you won't know that if you don't bother understanding the choices made in vanilla Rails.
> Each tool on the list (Vite, Tailwind, etc.) exists for a reason
Yes!
> and they're all necessary for a modern web application
No! Just as important as understanding the purpose of a tool, is also understanding when a certain tool is a bad fit for a certain project. There are no silver bullets.
The core rails philosophy has been, and continues to be, "reasonable defaults out of the box". In other words, if you are running `rails new` today, you should just start day 1 with the things that are preconfigured. One day you may need React/tailwind/etc, but vanilla rails will ship you to prod just fine on day 1 without configuring anything.
That doesnt mean you should rewrite an existing app to a more 'vanilla rails' config. You've already eaten the migration cost.
> Tooling isn't the problem: The complexity is inherent to modern web development
> Embrace the tools: Each tool on the list (Vite, Tailwind, etc.) exists for a reason, and they're all necessary for a modern web application. Saying there are "too many" is an amateur take on the reality of the ecosystem.
Depends. One can still write production-grade web applications with way less dependencies. You can write a Golang web server with minimal dependencies, keep writing CSS "like a peasant" and perhaps use jQuery in the client-side for some interaction. What's wrong with that? If you hire a strong team of engineers, they will be pleased with such a setup. Perhaps add Makefiles to glue some commands together, and you have a robust setup for years to come.
But some engineers feel that counterproductive. They don't want to learn new things, and stick to what they know (usually JS/TS); they think that a technology like CSS is "too old" and so they need things like Tailwind. Makefiles are not sexy enough, so you add some third-party alternatives.
Production-grade web app without advanced build tools? Depends.
CSS classes not scoped and starting to leak?
You hire more frontend developers and because there is no type system we get critical exceptions?
And no automated testing to discover them?
Correctly handling hyphenation of user-generated content? Safari decided to handle audio differently in the latest version and you have no polyfills?
iPhone decided to kill the tab because of memory pressure, because someone uploaded an image with exotic properties, and you have no cdn service like fastly image optimiser to handle that?
Support for right to left languages such as Arabic?
The backend returned a super cryptic response that actually originates from the users private firewall?
a11y requires you to use resizable browser text, and someone is using google translate chrome extension at the same time, and you can’t possibly know how the layout of the page will look like?
Some Samsung devices bypass browser detection completely and you don’t know if the user is on mobile or not? localStorage.setItem will throw an error when the device is low on memory, etc etc…
Once you get to a certain scale of users, even the simplest of tasks become littered with corner cases and odd situations. For smaller scale applications, it is not necessary to have a very wide tool arsenal. But if you are facing a large user-base, you need quite some heavy caliber tools to keep things in check.
You're not considering how scalable your simplified solution is to a team of 100+ people developing the same codebase.
Most of the problems of software engineering are not technical, they are social. Web development is simple for a team of 1-10. I love the idea of hand-writing CSS and relying on simple scripts for myself and a few teammates. Unfortunately it doesn't scale to large orgs.
Counterpoint: These tools add complexity, and you don't need them. If you step out of the system and look in, you see madness. The problems they solve are created by other tools; they are problem-generating systems.
That's like saying the Unix philosophy adds complexity because it dictates a tool should do one thing well. Composition of tooling (consisting of many individual tools) is the basis for lots of rock-solid stacks.
I don't think the Unix philosophy is universally correct either, but "too many tools" is a complaint without much consequential basis. It's an aesthetic problem not a functional one.
I am speaking specifically to examples used in the article, and related web dev paradigms that are popular. In the general case, there are tradeoffs to be made when adding tools, libraries, additional code of any sort to a work flow. In the case of web dev, adding these are bad tradeoffs.
You don't have any concrete complaint beyond the number of tools, and the nebulous idea that solving the problem each addresses within a smaller ecosystem would be somehow better.
Removing ESLint means... you don't have a linter. It doesn't have an upside. Removing Tailwind means you need to write more verbose CSS. Removing Babel means you have to use older JS idioms for browser compatibility. Etc.
I don't think complexity comes just from the number of tools, but the disparate things you "need" them to do. Redis, Vite, large CSS toolkits -- you're learning a bunch of large components.
I mean complexity comes from many places, but compared to the 'Unix philosophy' most of these tools are quite large. Obviously, there's quite a bit to learn about the way a *nix OS works, but if you treat tools as small and composable for simpler interfaces it helps a lot.
The web dev example of pub/sub is funny, because chances are if you're using Rails your primary DB (probably Postgres) already has a pub/sub system in or. Or you can just use any RDBMS for your job management system.
Not really I guess. Of course some tools are not mature, but many are mature and solid enough to solve real tech tasks.
Real problems are not caused by tools / problem generating systems but by silly people who fetishize complex tooling for simple jobs. Tooling is chosen not by merit but by hype.
I've been writing Rails code since 2007. There's a reason the stack has gotten more complicated with time, and virtually no team has ever done it right by this definition.
The trouble with an omakase framework is not just that you have to agree to the initial set of choices but that you have to agree with every subsequent choice that's made, and you have to pull your entire dev team along for the ride. It's a very powerful framework, but the maintainers are generally well-meaning humans who do not possess a crystal ball, and many choices were made that were subsequently discarded. Consequently, my sense is that there are very few vanilla Rails apps in the wild anywhere.
(I'm old enough to remember what it was like to deploy a Rails application pre-Docker: rsyncing or dropping a tarball into a fleet of instances and then `touch`ing the requisite file to get the app server to reset. Docker and k8s bring a lot of pain. It's not worse than that was.)
> I'm old enough to remember what it was like to deploy a Rails application pre-Docker: rsyncing or dropping a tarball into a fleet of instances and then `touch`ing the requisite file to get the app server to reset.
If this is what you remember, then you remember a very broken setup. Even an “ancient” Capistrano deployment system is better than that.
Or there was “git push heroku main” or whatever it was back in the day. Had quite a moment when I first did that from a train – we take such things for granted now of course...
Yeah, it also wasn’t difficult to do the equivalent without heroku via post-commit hook.
Honestly, even setting up autoscaling via AMIs isn’t that hard. Docker is in many ways the DevOps equivalent of the JS front end world: excessive complexity, largely motivated by people who have no idea what the alternatives are.
Me too. I'm not responding specifically to you with the parent comment. That said, "autoscaling", as a concept, didn't really exist prior to AWS AMIs (or Heroku, I guess).
My point is that a lot of devs reach to Docker because they think they need it to do these "hard" things, and they immediately get lost in the complexity of that ecosystem, having never realized that there might be a better way.
My recollection is that this is what many Capistrano setups were doing under the covers. Capistrano was just an orchestration framework for executing commands across multiple machines.
More than that, I worked for many enterprises that were using Rails but had their own infrastructure conventions and requirements, and were unable or unwilling to explore tools like Capistrano or (later) Heroku.
> More than that, I worked for many enterprises that were using Rails but had their own infrastructure conventions and requirements, and were unable or unwilling to explore tools like Capistrano or (later) Heroku.
Well, OK, so you remember a bad setup that was bad for whatever reason. My point is that there's nothing about your remembered system that was inherent to Rails, and there were (and are) tons of ways to deploy that didn't do that (just like any other framework).
Capistrano can do whatever you want it to do, of course, so maybe someone wrote a deployment script that rsynced a tarball, touched a file, etc., to restart a server, but it's not standard. The plain vanilla Cap deploy script, IIRC, does a git pull from your repo to a versioned directory, runs the asset build, and restarts the webserver via signal.
This was before Git! (Subversion had its meager charms.) Even after Git became widespread, some infra teams were uncomfortable installing a dev tool like Git on production systems, so a git pull was out of the question.
The main issue that, while not unique to Rails, plagued the early interpreted-language webapps I worked on was that the tail end of early CI pipelines didn't spit out a unified binary, just a bag of blessed files. Generating a tarball helped, but you still needed to pair it with some sort of an unpack-and-deploy mechanism in environments that wouldn't or couldn't work with stock cap deploy, like the enterprise. (I maintained CC.rb for several years.) Docker was a big step up IMV because all of the sudden the output could be a relatively standardized binary artifact.
This is fun. We should grab a beer and swap war stories.
Capistrano lost its meaning when autoscaling went mainstream (which was around 15 years ago now), yet people kept using it in elastic environments with poor results.
The primary benefit of containerization is isolation. Before docker, you'd drop all your code on a shared host so you had to manage your dependencies carefully. Specifically I remember having to fight with mysql gem a lot to make sure that there no conflicts between installed versions. With docker, you build your image, test it and ship it.
We had vm-per-app before docker, so it was still build the image, test, and ship, but it actually had everything it needed inside the vm.
Docker helps with the portability due to it's ubiquitous it is now, but it's not like the vm requirement went away, the docker image still generally runs in a vm in any serious environment, and a lot more attention has to be paid to the vm:docker pairing than the previous hypervisor:vm pairing.
It is very funny to me that the sibling comment calls this "a very broken setup" and for you "it doesn't sound like a big deal".
It's all about perspectives, or you really just never had to deal with it.
The happy path ain't a big deal. But think of the unhappy ones:
* What if a server gets rebooted (maybe it crashed) for any reason anywhere in the process. Maybe you lost internet while doing the update. Were you still dropping tarballs? Did the server get it? Did it start with the new version while the other servers are still on the old one?
* What about a broken build (maybe gem problem, maybe migration problem, may other). All your servers are on it, or only one? How do you revert (push an older tarball)
A lot more manual processes. Depends on the tool you had. Good tooling to handle this is more prevalent nowadays.
> What about a broken build. All your servers are on it, or only one?
The ones you pushed the image are on the new image, the ones you didn't push the image are on the old image.
> How do you revert (push an older tarball)
Yes, exactly, you push the older version.
The command pushes a version into the servers. It does exactly what that says. There's nothing complicated to invent about it.
All the interpreted frameworks use the same semantics, because it works extremely well. It tends to work much better than container orchestration, that's for sure.
> A lot more manual processes.
It's only manual if it's not automated... exactly like creating a container, by the way.
I use Kubernetes for almost everything (including my pet projects) and I see the value it brings, even if for increased complexity (although k3s is a pretty good middle ground). But none of these things you mentioned are unsolvable or require manual intervention.
> What if a server gets rebooted
Then the rsync/scp would fail and I would notice it in deployment logs. Or it should be straightforward to monitor current version across a fleet of baremetal.
> Maybe you lost internet while doing the update
True, but even Ansible recommends running a controller closer to target machines.
> What about a broken build
That's what tests are for.
> maybe migration problem
That's trickier, but unrelated to deployment method.
Never said they were unsolvable. You asked for elaboration about pains of back then before lots of the tools most take for granted existed. You seem to think we are talking about massive problems, but it's more about a thousand papercuts.
I sorely miss the sheer amount of utility that you can get from Rails out of the box for free compared to anything in the JS universe. Most JS devs don’t have the faintest idea how much they’re missing out on. Then again reinventing wheels is the JS way of life.
I really appreciate the power of JS's openness to writing entire new platforms. It's a great thing that everybody gets a chance to reinvent the wheels. It's great that many of these platforms actually just all more or less work if you use several of them at once. So extensible! So hackable! And you can host the entirety of them locally, so your whole site can be built in a permanently unchanging way? Wonderful!
But also, that kind of power needs a degree of restraint. You can do those things, but that means that it's on your team to prevent that one bored dev or that one guy who's just joined from a company who did things a different way from their instictive needs to add in new frameworks without a damn good reason.
When I bought a 3-D printer years ago, I had an important insight. I was either buying a printer as a project, or I was buying a printer to help with other projects.
Both are reasonable answers. It makes people happy to work on their 3-D printers. They love tinkering with them, like printing new braces, holders, parts, etc. The love tuning them. They love finding the perfect filament storage system. That's the hobby. The 3-D printer itself.
I was buying a 3-D printer to make parts. When I realized that I didn't want another hobby, a whole bunch of printer options fell off the table. I wound up choosing a printer that would pretty much work acceptably, once assembled. I have printed stuff with the printer, but I guessed right. At no time do I ever look at the printer as anything more than a tool to get something else done.
From my perspective, it feels like a lot of the JavaScript community falls into the former category. Their JavaScript environment is beautifully incomplete. It must be perfected. They tinker with the works to get the perfect packaging and build process. Bits and parts are changed out, re-worked, or re-written. I think the fact the language invites edge-cases also gives plenty of fodder for new ideas.
I'm a tool user, and that's what I liked about straight-up rails. It did a good job, was faster to develop on than enterprise Java, and the end-product was understandable. Rails and Ruby weren't my projects. The application I was working on was my project.
The JS universe moved quickly for about two years. The most popular frameworks at this point have been around since that time, with a few oddball upstarts. They've undergone some big changes, but are at the core the same concepts.
I recall evaluating Ember right around the time they switched from their last pretelease of I think 1.0 and suddenly all the documentation was either gone or out of date and not applicable. I ended up going with AngularJS (1.23 maybe?) and didn't look back until I went to work somewhere that used ember exclusively. It was far less pleasant to use than anything else I had been using up to that point except maybe Backbone.
There's been a few additions to the JS core APIs like webgpu and a few others, but all of them have been extremely niche. There's not much that's been added since 2016 or so that you couldn't pick up in a heartbeat, so it really boils down to the frameworks themselves. Ember lost to AngularJS, then Angular and React.
My reasoning for not using ember was it’s steep learning curve and easier libs(angular 1, backbone, react) to work with at the time(~2012 to 2014). Honestly, react wasn’t very big during this period, it was Angular that truly dominated.
IMO it's that frontend wasn't really a separate discipline at the time. Ember came out of Sproutcore, which was a framework created by some Apple MobileMe developers. They were building something that was very much an application development framework for single page apps before the term 'SPA' even existed. And I think people doing front end just weren't ready for that level of complexity yet. Most web developers were self taught and didn't have experience with UI frameworks and "real programming". At the time, doing frontend largely meant using jQuery to do ad hoc DOM manipulation and AJAX requests. Angular and then React came out and only tried to solve a subset of the problem that Ember was trying to solve, so they were easier for people to get started with. Then as time went on, it turned out that everyone did actually need solutions for everything else, but by then React had won.
I’d guess that it’s because React came around and it was from Facebook so it got a lot of adoption? Maybe there’s some other reason, the comment you responded to seems to imply something anyway
The way I remember it around 2006 there were a few up and coming web development shops in my town that had their practice centered around Rails. That last half of the decade I was working on advanced RIAs like knowledge graph editors and decision support tools using systems like GWT and Silverlight that were not Javascript but had the same async comm challenges.
Circa 2010 those people who were so successful with Ruby had come to the conclusion that they couldn't sell RoR apps anymore so instead they were struggling with Angular -- not to do anything they couldn't with do Rails but rather they though customers demanded applications that looked like Angular applications.
React was a big hit because it was an "Angular" which people could actually deliver working applications with. Its strength I think it is that it addressed certain concerns but left other ones unaddressed such as the theory of async comm. If there is a simple mapping between the state of the application and the state that is represented in the React tree life is great but I look back at the applications I was writing in 2006 and it still looks like a regression.
What I like about it is that I can draw absolutely anything I can imagine with it, even 3-d virtual worlds
Vue has a model which is closer to my mental model of web forms with first-class lists but I can see how to get into "you can't get here from there" situations.
I see the problem React solving is "how to compose an application out of components" and compared to WPF, JavaFX, and such, it's dramatically simpler, it's like a missing chapter out of Graham's On Lisp
I wasn't deeply involved in the Ember.js ecosystem as a user or maintainer, but the impression I got was that, for frontend purposes, clearer abstractions and simpler code was much more critical than "batteries included" frameworks like Rails.
Basically, if Ember.js used abstractions that were better for, say, extremely complex applications, it was dead in the water, because most applications make their library decisions when they are small and relatively straightforward. The market for javascript top-to-bottom rewrites of extremely complex apps (where something with those more complicated abstractions shine) wasn't really large enough for it to become dominant.
I also found it difficult to reason with, even though I'm an experienced Rails developer used to spooky action at a distance in the framework. Something about troubleshooting on the frontend really made it more difficult.
Javascript ajax was getting out of hand. Everyone wanted SPAs but managing the state of each button was becoming extremely unwieldy. Thousands of jQuery/js lines, the submit button wouldn't toggle to enabled once disabled...stuff like that. React came along and had prop state per element on a page (as they rebranded it, components), which helped immensely in this department.
Edit: and yes, as you said, it came from Facebook, so it wasn't just a solo developer's grad project; it had a large amount of support right out of the gate.
There's definitely a number of reasons, but I vividly remember _struggling_ with Ember data at the time. The framework itself was already complicated and the data management story felt immature and rigid in addition to complex. That definitely pushed me towards and a number of others towards backbone and eventually React.
I think it adopts some ruby conventions (one I discovered is the name in singular vs plural can mean different things like a collection and an item of a collection). I think there are a lot of conventions like this - you have to know.
I am not a UI developer and just needed to understand/debug something, it was not easy at all.
Batteries included backend frameworks exists in the JS ecosystem, just look at https://adonisjs.com/ . The problem is that the nodejs ecosystem started off with micro-frameworks as the antithesis to what they believed were “overbearing” frameworks, like rails and Django, at the time. I remember express’s selling point was to build quick and dirty.
Even from the POV of micro-frameworks, the JS ecosystem sucks. There's just so many competing half-baked libraries doing the same thing slightly differently and incompatible ways.
Compare this to the Ruby ecosystem, where every framework (including Rails) uses Rack, which means that all the frameworks compose together, if that's how you'd like to modularize your monolith. Or the other ecosystem known for its preference for libraries over frameworks, Go, where everything is standardized around http.Handler, so whatever you pick is basically guaranteed to compose.
And it's not just the lack of good overall frameworks, it's the general lack of good defaults for libraries in Node-land. Among the most popular ORMs/query builders over the years there are some surprising omissions, with Knex not supporting connection pinning or Prism not doing database joins by default for a long time.
> JS has multiple full stack frameworks similar to Rails. There is even a framework called Sails...
But it doesn’t. Rails is not just a full-stack framework. It’s the entire ecosystem of gems that magically just work together. What JS has is like the Temu version of Rails.
I don't know to what extent that's true compared to the npm ecosystem, but the js ecosystem largely rejects the monolith framework approach. It's focused heavily on frontend / browser, and the most popular JS frameworks are really just backends for frontend. Its most common to have a separate backend, perhaps in a different language, and it's an approach I prefer.
And I think rejecting the monolith is a massive mistake for the average CRUD app.
And it’s not like I’m not familiar with JS/Node, it’s the ecosystem I’ve spent the most time over the last 15 years. I’ve just seen so much wasted engineering effort in that time. Not sure what the exact multiplier is, but gut feeling says you’d typically need at least 2x the amount of engineers when using Node over Rails.
It's useful, but not necessary. Plenty of 10+ year old Rails apps in the wild. Github was running Rails 2.3 until 2018 while the entire software world that depended on it didn't fall apart. Even if you follow best advice and update your dependencies for security sake, you can effectively run the same code using the old "trends" (aside from things like safe parameters, etc).
Large rails apps tend to be on older versions not because they're so very stable but because Rails upgrades are a nightmare at scale. Even point versions have lots of undocumented breaking changes. There was a lot I didn't like during my 4 years as a rails developer but upgrades were the very worst of it.
> Every Monday a scheduled GitHub Action workflow triggers an automated pull request, which bumps our Rails version to the latest commit on the Rails main branch for that day.
it all depends on your philosophy on dependencies. if you maintain a small set of core dependencies that are there for good reasons and are actively maintained, then rails upgrades are pretty easy. if you have a Gemfile that has a bunch of third party gems that you bring in for small problems here and there, you have to occasionally pay down that debt on version upgrades. we have an 18 year old rails codebase currently on 7.1 that hasn't proven to be a big pain for upgrades. the hardest upgrade we did was because of a core dependency that had been dead for 5 years broke with a new version of rails. but that was a story of letting technical debt ride for too long and having to pay it back.
this is a common problem in any complex codebase that has a culture of using third party dependencies to solve small problems. you see this conversation all the time with modern frontend development and the resulting dependency tree you get with npm etc....
I remember that era, of using vanilla rails with server-generated forms and POST requests leading to more forms.
... even ten years ago, it felt pretty dated. Has Rails grown some framework-supported tooling for web apps yet, or is that the utility we're talking about?
> Then again reinventing wheels is the JS way of life.
There's some truth to this. The underlying notion is "how much computation do you do server-side vs. client-side," and because browsers don't run every possible language, the shortest path to client-side behavior is in JS. So there's a lot of wheel-reinvention in that sense.
(I do see the notion of writing the code once to run in either context wax and wane. boardgame.io is a JavaScript framework for writing turn-based stateful games; it uses a specific authorship pattern to run the core behavior library both server and client-side, so clients can responsively predict what will happen while the server steps through the rules and updates the game state).
I’m using Rails with IntertiaJS which allows React Vue or Svelte for your front end views for Rails or Laravel (made by Laravel).
Rails is amazing compared to NextJS or Express + React for me. Getting a lot more done. Writing a lot less code. The Rails ecosystem is great for doing a SaaS + modern content site/app.
I was away from Rails with full stack JS since before the pandemic.
I don’t think that much has changed with Rails since like Rails 4 or 5.
Maybe this is a recency bias, but for my own work or any work where I can dictate or influence the tech stack of a modern web app, I’m sticking with Rails/Laravel and React or Svelte when modern frontend/views are needed.
I don’t think Rails or Laravel should even focus on views that much any more in Ruby/PHP.
I get the best of all worlds now and I don’t hate JS any more. In fact I have sort of fallen in love with React as well now that it is only doing what it should do and I want to learn Svelte.
Stimulus and Hotwire are the "rails way" now. I've read the docs and they still confuse the hell out me. Seems like you're reinveting your own javascript components over and over again.
In my opinion Rails 8 + Intertia.js + React so much less "reinventing the wheel" (especially if you use shadcn components).
Going against the grain here, but I liked Stimulus so much I lifted it out of Rails and plopped it into a Phoenix app.
I think the problem here is a disconnect of assumptions. Stimulus isn't meant to be an alternative to React.
If your app is (tens of) thousands of lines of JS, and that is all you know a web app to be, then React may be a sensible, battle-tested approach for you.
But if all you need is a few dozen lines of JS to polish the UX of an overwhelmingly server-side app, then Stimulus is a neat way to encapsulate and surface it when desired. In Phoenix, it slots nicely between static HTML views and dynamic LiveViews.
I don't think anyone has ever suggested you should use Stimulus to try to replicate a SPA, and I imagine you'd have a very bad time if you tried.
This. We replaced Hotwire frontend with Inertia and it's night and day.
Unless you work 100% alone (and for a smallish project) hotwire leads to a real mess nobody can work on way before anything else I've ever seen in my life.
I'm a huge rails fanboi but the state of Stimulus and Hotwire make me sad. The concepts are awesome, and I think the execution might even be good. But the documentation is so incredibly horrible that I have a hard time even getting started, and I can't learn enough about it to answer the question of whether or not using it in any given project will end with me painted into a corner.
Stimulus is basically a very small event system with HTML hooks that integrates well with the Rails request lifecycle. I'd love to know if anyone has built anything sophisticated with it because I found it difficult to do anything remotely complex.
I've used turbo/stimulus/hotwire. It's best suited for STATELESS interactions withe the browser/web page. The problem is not all desired user experiences and use cases are stateless. And the ecosystem for hotwire is a minuscule fraction of all the other popular js frameworks.
If you're searching for inventory available its perfect. However if you want to update one thing based on the most recently touched input it becomes more complicated and in all honesty more trouble that it's worth.
Honestly if you're a solo Rails dev, use whatever you want. However the React ecosystem, and really all of the other popular JS ecosystems (vue, ), are very strong and you have so many available options. Stimulus is 2 steps back from jQuery, it inverted the Event delegation pattern. No one else outside of the rails community is using it.
I think the fundamental misunderstanding (for the majority of devs who dont "get hotwire") is that you can very often delegate the statefulness of a given interaction to A: The Server via the database or B: The Browser via localstorage.
If your page can be written with it's state being "reasonably" delegated to one of these two, hotwire is _all you need_. (To be clear, it's more common that you're just doing a bunch of work to duplicate state that already exists in the database/on the server, or handled natively by the browser, and by "delegate" I mean don't-duplicate-for-no-good-reason.)
There are many (but fewer than those who "don't get" hotwire believe) cases where it's more of a headache to delegate state to A or B. In which case you should absolutely pull in react/vue/<insert_js_framework>/etc. My go-to is: https://github.com/skryukov/turbo-mount + react because it minimizes it's footprint on the "omakase-ness" of your rails app.
Yes. It's also recommended to not use much of it and do almost everything else with turbo drive, or turbo frames, or with turbo streams, or with whichever convoluted magic you can do to avoid it until you can't anymore. Then you use Stimulus. Yes, I know it.
The fact people can't escape JavaScript doesn't stop people from being JS haters.
> The fact people can't escape JavaScript doesn't stop people from being JS haters.
It just creates more of them.
The nice thing about stimulus is that it binds the pages I'm making to the javascript. It's all easy to find.
90% of what I want react for is to update just part of the page. This is simple with Hotwire now. There is no added marshalling/unmarshalling of json -- just regular crud requests the same as everywhere else. There is no second programming language. There is no added toolchain.
Adding in Stimulus and I can do most of the other things I've been wanting to do -- like modifying dropdowns.
The one place I can see React perhaps being better is when something happens on the page and I don't talk to the server. For most of my business applications, this doesn't come up as much. But say I was organizing a schedule, only to submit it to the server at the very end, React might be better at dragging things around, labelling them, then one big update at the end. Maybe it's easy in Hotwire also, I don't know yet.
Are you familiar and adept with React/Vue/Svelte? I haven’t looked at Stimulus or Hotwire much yet. Just picked Rails up again a few weeks ago.
Tailwind and Shadcn (or similar ui) are standard for me now.
Most of the reason I've started losing interest in Rails and the DHH cult is their insistence that their homemade JS solutions (Stimulus, Hotwire, JS import maps) should be the default choice instead of industry standards like Intertia and Vite.
I am maintaining a Rails app with Vite + Interia + Vue, and it's many times easier to manage, develop, especially when working with LLMs that haven't been trained on DHH's new frontend experiments du jour.
Industry standards are not platform standards. React (enabled by Inertia) is in many ways is an industry standard for building UIs on the web today, yet it's not part of the platform. Same with Vite, it's the standard way to bundle on the web.
Decidedly, Import Maps are not used as a standard for dependency management in the web dev industry.
This is all moot because greenfield projects rarely exist anymore outside of being an entrepreneur, and if you're selling something, you're probably using a shopify wrapper of some sort 99% of the time. If you're working on a greenfield project at a Fortune company, then you probably have a bunch of considerations and in-house frameworks you'll use as a jumping off point instead of running `rails new` at any point.
These discussions are pointless and I'm a little fed up with them. As another commenter has pointed out, this exact same article (with the exact same conversational style) has appeared for at least 10 years, though I'd push it to 15-20. Write something new...BUILD something new...but for god sake's stop reiterating the same point because it's SO. BORING.
I couldn’t agree more, I’ve worked with Ruby/Rails for the past 10 years, and the youngest codebase I saw was 5 years old at that point.
I did work on greenfield Rails apps but they were API only “microservices” so none of this FE stuff was needed.
In any nontrivial company, the Rails homegrown FE solutions are ignored entirely because you can’t hire Hotwire devs but you can hire plenty of React/Vue devs.
Also, the Rails “FE” stack has changed plenty and it’s also hard to keep up with it (remember CoffeeScript?), is poorly documented beyond the trivial hello world and like I said, has absolutely no mindshare.
So these discussions are entirely disconnected from the real world.
> This is all moot because greenfield projects rarely exist anymore outside of being an entrepreneur, and if you're selling something, you're probably using a shopify wrapper of some sort 99% of the time. If you're working on a greenfield project at a Fortune company, then you probably have a bunch of considerations and in-house frameworks you'll use as a jumping off point instead of running `rails new` at any point.
I have no idea how one manages to be a HN reader and come out with a proclamation like "there are no greenfield projects left".
Neither venerable monoliths nor Fortune 500 companies represent the mean website. You're looking at highly visible outliers and ignoring the forest for the few redwoods that poke above the rest.
The care that's put into ensuring `rails new` creates something sane and basically production ready is exemplary. It's the missing middle between Hello World and terse API autodocs that so many tools just lack. Whether one uses Rails or not, this is something to emulate, not glibly denigrate.
I agree with the article; web programming is an absolute disaster of snowballing complexity. I think much of this is driven by a combination desire among web programmers to see themselves as "software engineers" and the need to constantly track the most fashionable trends and frameworks so they can one-up their peers.
I recently had to rescue a complex web-framework based system that was an absolute clusterfuck full of basic programming mistakes - the most glaring of which was a complete lack of database transactions in the node backend - but what it did have was every fashionable bell and whistle installed, and extensive reliance on the AWS ecosystem, as if it was designed for millions of concurrent users, whereas a single simple VM running about about 1% load would have done the trick.
And yet all this complexity actually did very little - a simple Rails-based-app would have done it all, at a fraction of the complexity, with far fewer dependencies.
Any project that doesn't need 30 or more devs with various specialties working on it all at the same time doesn't need the complexity that frontend/backend separation introduces. I learned this the hard way through years of over-architecting 1-2 person projects as a freelancer. Nowadays, it's just Django with a little bit of Tailwind on top.
I was hiring for a Django dev earlier this year. For the case study, almost all of them built a thin API backend in Django, and a React monster for the frontend (and in some cases, pretty much all the business logic). When asked about their motivations, almost nobody could explain it.
We hired one of the very few people that just used SSR.
i can explain it. (ok, i can't explain why someone would create a react monster instead of using a better suited frontend framework, but i can explain why i prefer to separate backend and frontend)
ever since i started using frontend frameworks for websites, the backend has become trivially simple. so simple that i have been able to reuse the same backend for all my websites built since. most websites do not need more than CRUD on the backend. and even for those that do need more backend logic, separating front and backend makes both parts easier to develop. they don't get entangled, and i can make drastic changes in either part without breaking the other.
frontend frameworks allow me to think of the frontend as an independent client application that runs in the browser. instead of having a complex application that displays here but runs over there, i have two simple applications, one that runs on the server and one that runs in the browser.
using a frontend framework makes development feel like writing a desktop application. i don't have to consider network latency, except to load and update data. but that can happen in the background. it doesn't affect the UI. it makes me think about loading data from the server efficiently. it allows me to preload data in the background. it allows me to cache it so that when the user switches between different views, the data doesn't have to be reloaded, yet it can still be updated.
you can do this with a server framework only too. but getting that working smoothly across multiple page loads is a lot more complex than having all views that share data in a single page application.
I like that too, in theory. We used to call that "rich client". Basically UIs that had full database access.
And there begin the problems. Do you really want to expose a full CRUD API, or are there consistency/security rules you want to enforce? That's cool, but makes API design a little more challenging and frontend development a little more frustrating. SSR eliminates a lot of these problems, and for many types of software, it's quite sufficient.
For a lot of software, it doesn't make that much sense of course, e.g. if you need clients for multiple platforms.
That's the kind of conversation I wanted to have with the candidates that went for that architecture.
Do you really want to expose a full CRUD API, or are there consistency/security rules you want to enforce? That's cool, but makes API design a little more challenging and frontend development a little more frustrating.
fair point, however i don't see that as a drawback. the security/consistency rules you want anyways. and an API makes it easier to enforce them and not allow people working on the frontend to get around them because they have direct access to the database. in difference to what you said, i believe the benefit of a rich client is that it doesn't have full access to the database, but only the access the API provides.
i also don't feel that it makes frontend work more frustrating, on the contrary, it means i don't have to worry about access control in the frontend because the backend is supposed to take care of that.
to give an example: if i want to limit the size of the text field, i have to implement checks twice, once in the html/js, to help the user, and once in the database access to make sure the user didn't cheat. i have to do that regardless of whether front and backend are separated or not. it doesn't make a difference. but the separation ensures that the frontend code can't get around the limit.
where it does get frustrating is when you have different teams that have to communicate and agree. but the problem there is the team size, not the architecture.
this subthread started out with the claim that small teams don't need the complexity of frontend/backend separation introduces. that's where i disagree. the complexity shouldn't be an issue. as i said, i find it reduces complexity. a small team also won't have the communication problems when disagreements arise over the API. they can handle that like disagreements over the class hierarchy or datastructures or whatever. you talk about it, make a decision and everyone is on the same page on what to implement.
That's the kind of conversation I wanted to have with the candidates that went for that architecture
"Islands" are really nice for this. The highly interactive pieces are usually only a small part of the app - just mount a component there if it's suitable. You don't need a full blown SPA
Islands probably have some runtime performance benefits, but the dev experience and build-time complexity is probably just as high or higher than most JavaScript SPA setups.
That might be a case where you want a SPA + backend API. But the point is that in many cases you either don't need a highly interactive frontend or the frontend is not that interactive (ie. progressive enhancements work).
Ime progressive enhancements are brittle and hard to maintain. If your site doesn't need any JS it's fine, but as soon as it needs some interactivity beyond the absolute basics you benefit from having reusable components and automatic change detection / data binding.
I fail to see the connection with jquery. Anyway brittle and hard to maintain is what we experience now with frontend stacks and codebases with very short lifespan. I can't keep track of components libs du jour that come and go and keep being reinvented with very little value added on each iteration, along with constant api breakage. Brittle, indeed. Meanwhile, Rails and Django have been rock solid.
Both jquery and htmx style approaches lack the concept of components, data flow, template binding etc. At most you get string templates. You end up manually wiring up dom updates when state changes, and that kind of thing is brittle and is why stuff like React was invented in the first place.
React has been very stable throughout its life time. You can run 10yo react code in v19x without issues.
In most industries, your clients won't care if the software relies on an ultra scalable architecture split in microservices or a monolith + PostgreSQL.
In every project I ever do, I start with a server and a postgres database. Every addition to that architecture has to be rigorously defended. So often people add complexity for absolutely no reason. Once you actually start scaling then you can worry about the problems that you think you might have.
I think some people are so fixated with keeping up with the latest tech and prepare their project to scale infinitely that they have forgotten how good barebone setup is, especially with Rails. I get it, it's boring, unentertaining and might be understimulating to some. But it just works, Rails is truly batteries-included. Stop with the overengineering
i came back to rails after a very long hiatus to help a company bring a 10+ year old rails project to Rails 8.x.x from Rails 5. It took a bit to get back in the saddle, but every new project I’ve started since that’s a SaaS/CRUD app of some kind it’s in Rails.
I’m finally at the age where productivity is infinitely more important than anything else.
A few weeks ago because there were 2 HN comment sections shitting on NextJS endlessly, I decided to go back to Rails.
I have ported a chunk of my likely last full stack JS project over to Rails with AI vibe coding everything as a reference for me to redo it again with AI but not vibe coding.
Absolutely amazing work. About 40% of that NextJS app was vibe coded and the process of undoing the excessive and verbose code was depressing me.
The Ruby and Rails code is simple and understandable and a fraction of the lines of code.
Last sentence exactly. I am using IntertiaJS for some of the frontend and I finally don’t dislike JS any more. React is amazing when it’s only a view library.
are you dabbling at all in the “no build js” stuff that Rails 8 supports? i did it for that corporate project and their deploy time went from 30 minutes to 5 minutes. it’s also such a headache reliever but removing most of the confusing aspects of the JS ecosystem for me.
It was real over a decade ago. This is sheer stupidity and selfishness of bringing hobbies into their jobs. If it makes Front-End devs feel better, the "DevOps" world isn't much better.
Imagine you want to deploy some microservices to Kubernetes. You can just create EKS/AKS/GKE cluster from the GUI, `kubectl apply` a few resources and create a load balancer to point your domain there. That will work. But...
You probably want to automate the infra creation (so Terraform, Pulumi, CDK...), you want to automate building (so GitHub Actions, Jenkins, Bitbucket Pipelines, GitLab CI...) and artifact storage (so Nexus, Arti, ECR, GHCR...), you want to automate deployment (so Argo, Flux, Helm, Kustomize...), you want to automate monitoring (so Prom stack, Datadog, many APMs, Splunk, Graylog, ELK... could easily name a dozen more).
Each part of the stack can easily bring a dozen different tools. I work in SRE and I use at least 40-50 tools for a mid-sized project. And this is "normal" :)
Meh. For a long time people have been saying stuff like "devops is dead, long live the platform engineer" exactly because the figuring-out-what-works phase of wild experimentation is over and there are unambiguous "winners" for technology in most every niche. You've listed lots of commercial vendors and alternate choices for backends/front-ends here as if to illustrate a lack of standardization in tools/frameworks, but is it really?
Whereas churn in web-dev seems self-inflected.. devops practitioners don't actually create vendor/platform fragmentation, they just deal with it after someone else wants the new trendy thing. Devops is remarkably standardized anyway even in the face of that, as evidenced by the fact that there's going to be a terraform'y way to work with almost all of the vendors/platforms you mentioned. And mentioning 20 ways to use kubernetes glosses over the fact that.. it's all just kubernetes! Another amazing example of standardization and a clear "winner" for tech stack in niche.
Well, many years ago you could use CFEngine, Puppet, or Chef, or Ansible, or Salt/SaltStack, and then later Terraform, Otter, Pulumi, and now we have Nix, and a Terraform fork as OpenTofu.
Not all of those tools do identical jobs but there's a ton of overlap within them and they all have idiosyncracies.
and the problem is that if you apply for a job in this area you have to know them all +10 years experience with all the frameworks and backend stuff, sql, docker
It's not so bad if you're doing it professionally because you pretty much set it up once and you're done. But yeah it's annoying for one-off projects or if web dev isn't your main job.
That said you can avoid it. I wrote a website using Fresh (https://fresh.deno.dev/) and that was the only thing I needed. Incredibly simple compared to the usual Node/Webpack mess. Plus you're writing in Typescript, and can use TSX.
I probably would set up ESLint if multiple people were working on the project. But you can definitely start without anything else.
This is cute but fails to mention how many times in the life a rails application we have to go from bundler to webpacker to sporkets to Propshaft and importmaps to jsbundling. Or from autoloader to zeitwerk or from Turbo to Hotwire and god knows what else.
Take a look at ads on rails newsletters and how many of them are professional services to upgrade your rails app.
I’m glad someone called this out. “Let’s just use vanilla rails” — sure, except basically every version of rails for the past 5 years has decided to completely change how they do JS.
So many gems are also still built on sprockets — even when you want to use the “rails” way, you are stuck now with a hodgepodge of JS anyways.
It’s a mess — maybe one day we’ll get it fixed, but don’t pretend it’s not partially rails fault as well.
This scenario is worse now than it used to be, but the concept isn't new. I remember wanting to tear my hair out learning Django 15 years ago: The tutorial had you install Vagrant, VirtualBox, and Chef in specific versions, all of which were broken and/or a pain to install!
I still use and love Django, and don't bother with that stuff. Django Rest Framework was another distraction.
I would really like to hear from people who have have hacked together their own code generation tools for production projects, including taking an existing tool and extending it for purpose.
Did it work well? Any lessons that others should know of?
I've built dev tooling for local deployment management and release automation and those have worked well, but the code generation piece is something I'm curious about.
I agree with the sentiment on this. I'm building applications that are easily converted to native mobile apps with minimal code and engineers left and right are telling me I should use 60 different libraries and frontend tools to reach the same goal.
Meanwhile Rails is becoming easier and easier to run complex apps with much smaller teams.
This is the fundamental weakness of Rails. You can't just "do Rails" because the UI out of the box isn't usable. You've always had to add something on whether that was Bootstrap 10 years ago or React today. It's always been a bolt on and always has been changing.
I haven’t really found this to be true. You probably wouldn’t want to build Figma in Rails, but the average SaaS CRUD app is a perfect fit for Rails with a sprinkling of Turbo Frames.
It’s usually the lack of non-React knowledge to know what does or doesn’t require React.
That's a weakness, and strength, of all server-browser architectures. The world (or Apple) decided that a unified front and backend (ala Flash/Flex) wasn't optimal.
I'm going to make the case that it's actually the opposite. Rails might seem simpler out of the box, but this is all surface level. Rails is massive and extremely complex, especially its ORM, which encourages really bad database practices in my experience. And it doesn't have strong typing.
If you went head-to-head with Rails on a slightly complex project with say shadcn/ui, Convex DB, and TanStack Start, I guarantee you, the TypeScript app will be much simpler and give you more power than Rails, especially when building the UI. And to top it off, you will have strong typing everywhere -- from the DB schema to the URL routes.
And bonus, deployment is simple. ConvexDB already takes care of the backend and the frontend could be deployed to something like Cloudflare Pages.
Why would you not be able to build a "web analytics tool" with what parent comment mentioned? At the end of the day it is just data and if you are just starting out pretty much anything will scale and if you already have millions of customers you also have capital and people to think about how to make some homegrown solution to specifically cater to that.
The market for these new breed of frameworks is not huge companies with crazy scaling needs but freelancers and your very early stage startups who haven't even found a product market fit since they are starting new they don't have anything to loose with newer stuff and chances are that newer stuff also helps them do more quickly like I haven't used convex but on it's marketing page it does mention a lot and same for other frameworks like pocketbase or SvelteKit combined with a db etc. Like always there is no silver bullet and every stack can seem "random"
If you're gonna rant about the JS ecosystem at least get it right. You can set up a Vite + React + Tailwind setup with two commands
npm create vite
npm i @tailwindcss/vite tailwindcss
If you want automatic code formatting and linting install biome, that's one more command.
You don't need to think about React Refresh or babel or typescript, it's all handled by vite. I've never even seen a .babelrc file. And why does the author add husky?
Like, if you want to criticize JS fine, but chose valid criticisms. This just sounds like the author hasn't actually used modern js.
Use NextJS, then. I think everyone in this thread and the author of the post is intentionally choosing sub-optimal setups for the side they don't like.
what’s interesting is how every few years we circle back to the same conversation with new names for old problems. the industry keeps rebranding the same complexity as innovation, but it’s mostly the same tension between abstraction and control. every new framework promises to simplify things, but each simplification hides an entire new layer of assumptions that developers eventually have to learn anyway. maybe that’s just the cost of building software at scale now: we’re layering human preferences and historical context into the codebase as much as we are logic. in that sense, modern stacks aren’t complicated because of bad design choices, they’re complicated because they’re living artifacts of collective compromise.
I just use most of the tools that are mentioned. They just work, if you pick the right bundler (Vite is a good pick). It's like Linux, it requires hundreds of packages/tools to run, and nobody complains about that.
I get the spirit of the dialogue. And feel quite similar. But I have some quips over things that are blatantly misconstrued:
- you wouldnt use vite then also add next or remix
- if you're using vite, next.js, etc. you're not going to need to add nor configure babel
- vite, next.js, etc. starters come with pretty much all of these separate things he mentions included. typescript, prettier, eslint, tailwind, react etc. You know, like a batteries included framework.
Hot take, rails is much better as an API only, and do something else for serving your frontend. It comes down to the fact that there is no clean and bulletproof solution for building responsive websites anywhere.
You could do the exact same breakdown describing the pieces of rails you need to learn to accomplish the same things, just because they are more separated libs in the front-end doesn't mean the problem is simpler if you solve it with rails' chosen tools vs the popular npm solutions.
The one thing I don't miss about Rails is constantly feeling like I'm doing it wrong. I had a 'discussion' at RailsConf when I was told I should stop using C Ruby and switch to JRuby because it's so much better. And that's the right way to do it.
But I couldn't get JRuby to package reliably. I'd fix the issues, it would work for a while, and then something would change.
Oh... because I wasn't doing it right. I have to rework a bunch of dependencies. And after a while, it breaks again. Why? Oh... I wasn't doing it right, I should be using this middleware instead...
So I said I'm done mucking around with JRuby. When I said this, I was told at RailsConf that was doing it wrong, and by implication, irresponsible with my clients' applications. That was I setting everything up for failure. Yet the applications that were working just fine on C Ruby. (I don't really hear much about JRuby any more - but I haven't been part of that world since George "strategery" Bush was president.)
And this was the shtick for conference speakers and YouTubers. You're doing it wrong. Do it this way to do it right. You're using Controllers wrong. They should be fat. They should be thin. They should be big boned. You should never use models. You should only use models. You should sit on two chairs and pair program with yourself when you develop. Only drink water when writing tests.... etc. etc. etc.
This left a bad taste in my mouth in what otherwise was a great community. I felt like a lot of the community wanted to do build great applications, quickly, cost-effectively, and with high quality. But that same impetus could be manipulated by folks in a way that's unhelpful. THAT part of Ruby I don't miss. RailsConf in Portland, eating VooDoo doughnuts, talking shop with other folks? That I miss.
Then you watch someone use Hey.com for 10 seconds and realize that it's kinda embarrassing to have a worse web mail client in 2025 than Gmail was in 2005. And you probably actually do want a JavaScript SPA if you want to match Gmail's interactivity.
Well yeah, if you are just trying to have "blazing fast navigation and working forms" use Vanilla Rails. If you have the need for lots of javascript interactivity, you'll probably want to hire devs that are well-versed in Javascript frameworks. Try convincing them to just use Vanilla Rails and tell me how that goes.
No, just no. Or maybe it depends. But if you want to provide a lovely, modern, interactive frontend, you can't just blindly ignore what evolved on the frontend ecosystem for the sake of your purity. It's arrogant and dismisses all the people who love to craft enjoyable frontends.
Following some thoughts about how to merge Rails and modern frontend approaches and how Inertia finally solved that question for me.
--
I consider myself more frontend focused but I have a deep love for Rails and some advanced experience, for sure less than in frontend though.
I tried hard following the route of hotwire, stimulus and friends knowing that DHH and the rest of the community loves those JS patterns.
Creating reusable stuff, cresting just a little bit more complex components, sharing those components through the UI.. it's just horrible cumbersome, repetitive and far, far away from all those best practices and patterns we've developed in the frontend.
I tried creating a diff viewer with comment functionality with stimulus. It worked, I was kind of proud but it was cumbersome the define components and share functionality. Maintainable? No way.
Then I wanted to create a double list where you can drag items from left to right. It was the hell to include css, js, manage the hierarchy and then I just gave up. I was demotivated by the constant nagging of my brain how much more simple this would have been with a single, simple react/vue component.
Then I went the wrong route: Rails API plus React. That's just giving up on most of what Rails gives you and I wasted ton of my time creating an additional auth layer on top of the session that Rails would give me. And then the horrible duplication of your state. One in Rails and then the same stuff in React. The same nagging in my brain now told me: That's wrong.
And then I found the holy grail of modern Rails development: Inertia.js.
I heard about it very often but never at the right time. So I forced myself to try it out.
And here I am: I use Rails with Inertia Rails. I have the full pleasure of Rails but I can create React components that represent any page I like to write in React. Inertia will serialize and pass in the data from my controller. So no state. Just pure UI building.
If you love Rails and the frontend: Try out Inertia. It feels like I'm using the best of both worlds. The layer inertia creates is very shallow and optional. So the risk is low.
If you like the "just rails" with no JS or CSS preprocessing at all (including no node dependencies), that's great.
I think that's still pretty ridiculous though.
I find that Rails+vite is a pretty nice sweet spot that really does just work. It's far far better than trying to use Rails with that "webpacker" chain or anything like that. i like that vite can do my CSS and my JS preprocessing needs, so it's just ONE thing, vite, and I'm set.
(Hypothetically you can use some light weight NPM dependencies with "just Rails" (really a weird take on importmaps, not "just rails"), but unless it's ultra simple it gets just ridiculous very quickly. Vite does not. I think the "no need for any real npm dependencies or other preprocesing of your JS, or CSS" dhh take is a weird one. Fortunately everything still works great if you agree with me.
I just woke up from a nap and I see "You're Doing Rails Wrong" and then I wonder... is it still 2008, did I imagine Brexit and why does my macbook's screen look soooo good?
Minification... how many times have I seen devs claiming that adding a whole toolchain for saving a few kilobytes is crucial to performance and simultaneously failing to serve assets with proper compression and cache headers ? Heck, how many times have I seen "web" devs with no basic understanding of the HTTP protocol ?
And they look at me like I'm the lunatic when I tell them their 3 text fields 2 buttons "app" is over-engineered and needs no build step.
>I just can't understand even using Rails for web dev.
Some people are building real web applications, not PHP toys. I get not wanting to keep up with the latest JS insanity, but simple MVC frameworks are popular for a reason.
Rails apps are rare and getting replaced. Most web apps are static builds where the tools listed are not used all at once and largely irrelevant outside the dev environment.
> John runs a single command. The app boots instantly, working forms, instant loading times, blazing fast navigation.
Meanwhile in the real world - users do not care at all if it's a Rails app with refreshes or a React app. In most cases, the Rails app is actually better due to its simplicity.
The question I think we should be asking: Why? Why are we replacing everything with React and a bunch of other libs on top of it?
The front-end dev space feels like a cacophony of people all blurting out the same over-engineered stack. If your app is a few lists, a chart, and a form... Does it _reaaallly_ need React?
37signals is afterall running multiple successful products with Rails, and one of them is an email client.
> The front-end dev space feels like a cacophony of people all blurting out the same over-engineered stack. If your app is a few lists, a chart, and a form... Does it _reaaallly_ need React?
If your app is that simple you don't even need Rails.
In my experience, everything starts that simple. But then time passes, team members rotate, and... your PM keeps asking to add more and more features... And that's when the "simplicity of hotwire" becomes a nightmare to maintain. And guess what, the next dev that comes to the project will hate all the hotwire crap, and whoever built it.
It's easier to make a simple list and a form with React/vue/svelte even if it seems overkill at first, because when things get more difficult you already have the big guns. If you start with the tools to build simple, well.... wish your project stays that simple forever, or that you're given enough time to rewrite everything.
> 37signals is afterall running multiple successful products with Rails, and one of them is an email client.
These applications may be a successful product, despite of hotwire, but they're not a good example of anything. They feel like shit to me (using them from Europe). And again, the main problem is not the end result but the maintenance. If there's anything we've got from all of this mess, is that implementing UIs as "components" are the best idea in the last 10 years.
Stop beating the dead horse of variables interpolated in templates. It just doesn't work (unless you work alone).
It’s just Basecamp and Hey now right? I liked when they had more than 2 products as a reference for Rails apps. I still feel immense nostalgia for Basecamp 1 and Backpack It.
—-
I love Rails but disagree. Using InertiaJS and React, Vue, or Svelte for some of the front end/views makes too much sense. The new Rails Way should be optionally allowing this.
$1M ARR and 10k+ emails? Those are rookie numbers. There's nothing special about a rails app achieving that.
You'd be surprised what kind of far worse junk than anything we're talking about can scale the same or better and is ergonomic to another type of dev. This is all just bikeshedding.
Software complexity is bikeshedding? I disagree. I think it's one of the most important things, especially for startups.
Of course Hey is still young... But I'm pretty sure you also know that they have Basecamp with 3M+ users. I mentioned Hey because I think it's a great example of sth more than lists/forms.
At some point, the business cannot be just one app or one tech stack. More devs will come aboard that disagree with the chosen tools and for very good reasons. You must work with the devs you have and the expertise they bring. Only the most out of touch CTO would avoid sunsetting legacy apps. There's the business side concerned with functionality, and then there's the hiring side concerned with implementation details. Both are key to getting the best devs and the best results.
Wait until you find out how many YC startups use Rails...
Or how big Shopify is. Or how many other large companies use it. And how many startups use it but just don't talk about it because it isn't cool anymore.
I think there is a much-better-than-merely-non-zero chance that the rise of coding agents will also mean a rails renaissance. All of the complexity identified in the article really gets in the way of LLMs.
Rails “convention over configuration” approach is probably also more LLM friendly. Convention can be trained into the model itself, whereas configuration takes up precious context.
I have definitely found this. A few months ago I tested Claude coding a web task in Rails vs Flask. Claude did much better with Rails - I think the opinionated Rails conventions helped the AI. However, Claude didn't complete the ask in Rails. A couple of weeks ago I revisited a similar task with one of the latest AIs. It sailed through it in Rails (didn't try Flask).
> (John runs a single command. The app boots instantly, working forms, instant loading times, blazing fast navigation.)
Sure it does. If you're not using Vite, how are you bundling? Oh, you're not bundling? I guess that means you're not using TypeScript? Interesting, how do you catch errors? Oh you just let things crash in production? How do other engineers understand the intent behind your code? Oh they don't I see. If you're not using React, what are you using? Vanilla JS? Have you considered that it's a statistical fact that every single person who has said "I don't need React, it's just a big complex mess, I'll just invent it myself" ends up creating an informally-specified, bug-ridden, slow implementation of half of React? Oh you don't use Prettier? OK, how are you formatting your code? Oh you're not, it's just a giant mess? Oh you're not using ESLint, interesting, how do you keep code consistent across your team? Oh that's not a concern? Hm.
Almost every technology in the article exists for good reason, and solves a real issue[1]. Maybe not an issue the author has encountered, but the author shows no understanding of the issues they are solving, and the final "punchline" implies that anyone could just toss all this tech out and improve their developer experience. "Learn the rules before you break them" applies here.
This is an uncurious article which mocks at abstractions rather than taking the effort to understand why they exist.
[1]: OK, I do think some abstractions are more trouble than their worth. But why did the author choose all the reasonable ones, like React? Why not dunk on Angular, I mean come on!
The problem is these issues are only issues for a certain subset of software. Many, many pieces of software don't need to be very robust, don't need to be developed by a team at all, and the occasional runtime bug is well worth the literal cost of maintaining compatibility with dozens of packages.
Correct me if I'm wrong but I believe you're interpreting this as if the rails app needs the same amount of is that exists in the described vite solution.
But in reality if you're using hotwire you can get away with almost no JavaScript at all comparatively. That's why stimulus is in vanilla js generally, it's meant for sprinkling behavior onto the dom vs controlling the dom.
So if you don't have a js framework that needs to control the whole Dom and doesn't need a gigantic optimization step or tree shaking or typescript or whatever, you can get away with a whole lot less than it you embraced those frameworks that _do_ want to own the dom wholesale.
I think the point of the article it's that these tools are redundant since rails a full stack framework, already has the features to help you make a web app
Really love that a main criticism is missing static typing in a Ruby system. I assume the Rails devs know how to work with dynamically typed code on the backend — the same practices will work fine on the frontend with vanilla JS.
If static types are so fundamental for you, I'd suggest skipping Rails entirely and reading other content.
> how do you catch errors? Oh you just let things crash in production?
You write code differently, and you write tests. Rigorously testing business logic also has the nice side effect of catching type errors. "crash at runtime" in the real world means "crash in your tests". I've written a tonne of Ruby and it's simply not an issue
Plenty of businesses have been built on the back of dynamic languages. Nubank runs their somewhat critical business on millions of lines of gasp dynamic Clojure
> ..ends up creating an informally-specified, bug-ridden, slow implementation of half of React?
VS Code is written with custom JavaScript
Obsidian is written with custom JavaScript
Here's one reason to do it: the churn in these ecosystems is insane. Imagine writing a huge app in backbonejs back in the day when it was popular.. and then subsequently abandoned as people moved on to the new better way. That's an existential threat to your business if you're a small team. Even a big team takes a huge hit there
Vue2 to Vue3 was a shitshow. AngularJS -> Angular 2..
I'm still annoyed at React Query straight up deleting the documentation for the version a project I was on was using. Rails still has their docs up for the version released in 2009? The JS community just doesn't care about longevity
What happens when the React team decides "oh well actually WASM is the way forward" and redoes everything.. or maybe Svelte ends up taking over 4 years from now? Or hell if they even just evolve the framework in a direction that isn't in line with with what you want out of it
You're not getting it. A modern Rails 8 application has so few lines of JS that you don't have to deal with all the problems you introduce with a heavy JS application.
Tooling isn't the problem: The complexity is inherent to modern web development. You see similar "hidden" complexity in other frameworks like ASP.NET, and GUI desktop frameworks as well.
If you're using Rails as an API backend with React handling the frontend, it's almost a completely different application architecture than a traditional Rails monolith. So the list of tools (Vite, React, Prettier, etc..) is almost for a completely different problem (again, unless you use Rails for FE; if you want to use Rails for Frontend, use Rails for Frontend; not a fan of the mash-up at all.)
The real issue is learning methodology: A lot of developers today start their careers with frameworks (point 4) before learning the fundamentals of the web (points 1-3).
HTML for markup.
CSS for styling.
Learning server-side logic (e.g.: <forms> can POST and can return a completely different page at the same URL) and databases for dynamic content.
Then, JavaScript for interactivity.
Embrace the tools: Each tool on the list (Vite, Tailwind, etc.) exists for a reason, and they're all necessary for a modern web application. Saying there are "too many" is an amateur take on the reality of the ecosystem.
Hotwire is sort of vanilla rails and it enables you to create very modern experiences with content live updating through web sockets and it is basically a one liner to setup.
The de facto way to deliver JS in rails has also become far simpler through import maps. There is no build step for that. Tailwind support is a flag away when generating a new rails app and is super simple.
Deploying has even become simpler through kamal.
So no, complexity is not inherent to web development and the article is wrong in marking Hotwire as “complexity”. If anything it makes it simpler.
I agree with your point about learning, but learning shouldn’t be about learning more tech. The learning should be how to get more done with less. Anyone can use 20 different programming languages and servers, the skill lies in using 4 of them to do the same and outperform a thousand person team with just 3 devs.
>> "Hotwire is sort of vanilla rails and it enables you to create very modern experiences with content live updating through web sockets and it is basically a one liner to setup."
My point was that web development isn't complex, but the core is simple; but modern web development is.
Your "Hotwire is sort of vanilla rails" statement is a perfect example.
What you claim to be simple, is a big list of tooling, web-sockets included, integrated together. The end result is using it might be a "one-liner", but that doesn't mean it's simple. And that's OKAY. Because simplicity should be the standard; and adding things, like sockets for live updates, should be something you explicitly enable (with modern web-apis, its definitely simpler than it used to be, but that doesn't mean its simple)
Data is sent to React by inertia/graphql/whatever and React renders it. It’s pretty straightforward.
Edit: I do love LiveView/HotWire/HTMX etc but honestly everything is a trade off and there are times just rendering a react component is less complex.
The more stuff you add on the harder everything is to understand, and the less stable your app becomes until suddenly you need specialists for every piece just to keep things chugging forward. Everything needs greasing and maintenance over time..
..and then in 4 years the React team decides "oh you know what the way Svelte is doing things is actually way better.. we'll need a re-write to integrate their ideas". Now what?
"that wouldn't happen! so many businesses depend on React!".. uh they have no obligation to make things compatible with whatever you've built. They're not working for you. What happened with AngularJS? Vue 2?
Hotwire is easy to understand (React "just renders it" is a massive oversimplification)
If Hotwire rewrites? I create a private fork and continue on. Who cares
If I want to tweak how Hotwire works cause it'll benefit my app specifically? I do it myself
I'm not against adding complexity.. but if you care at all about longevity and long-term productivity then adding React really needs a tonne more consideration than it gets
But maybe I'm biased because I've been working with React for a long time, I don't find it too daunting to manage dev tools around React. When React was young, I remember that there were _a lot_ of ecosystem churn but now it's more-or-less settled and I don't think it's too bad.
I don't know how Hotwire works that well as most of my experience is around Elixir's LiveView, but at least for LiveView, there is also quite a bit going on under the hood to make it performant for large lists and to handle error states gracefully. And I (maybe incorrectly) assume Hotwire is similar, so I feel like it may not be not as simple as you say. (Edit: it is simpler than React though!)
Given the speed of rendering that browsers achieve, I would say that their call stack during this is highly optimized. I don't see OS doing much at all besides sending the drawing buffers to the GPU.
When every other learning resource is titled something like "Ten reasons you need to be using the MONGOOSE stack right NOW!", it's no wonder we've got people trying to shove redis into their baking blogs.
Matter of fact is, the average website would be fine without a "stack" of any kind, but no YouTuber sells sponsorships telling their viewers that. Ergo, many junior devs genuinely don't know that.
While I agree that people should be primarily learning the core tech, it's a difficult message to deliver amongst the cacophony of corporations trying to promote their services.
What it did lack, though, were fancy widgets and other decorative bells and whistles. But is it worth the cost of pulling in the vast overhead of "modern" frameworks, and their resulting complexity and maintenance problems, just to have those?
This is why I don't want to do much frontend in businesses, where there is a separate dedicated FE team. It seems to me, that traditional fullstack devs, not FE devs who want to do backend stuff in NodeJS, but devs who happen to have learned web standards like HTML, CSS, and JS along the way, not as a "one ring to rule them all", make better websites. Maybe not as fancy optically, but often more responsive, and better in the listed aspects. But this may be bias, because such websites are far and few between these days.
It sounds ok to adapt tools if needed (won’t get into whether tools are actually needed, let’s assume they are).
But Rails is supposed to be a giant, everything and the kitchen sink framework bringing everything from an ORM through its own console to scaffolding code generation.
If adding tools to the setup is needed, isn’t then rails the thing to reconsider? Something more modular could probably work better.
Just reading “vanilla Rails” sounds like a red flag. How can that behemoth be considered vanilla?
All the tools on the article are about client-side rendering and operations.
It's ok if Rails decided to have opinions on client-side rendering and operations now, but it's far from expected. And it would alienate some users.
Instead, the article's conclusion is the correct one. You don't need to mess with complex client-side and ops tools if you don't want to. You can build many things perfectly well without them.
On the other hand, Rails has had client-side opinions basically forever; when I started using Rails during the 2.x days in like, 2009, there were helpers that injected JavaScript to make forms better, Rails 3.1 included the asset pipeline, an attempt to compete with webpack, in 2011. Even the current generation of these things has been around for a long time, Hotwire is four years old at this point.
Absolutely true that not every app needs to be a SPA from day one, but I do with there were a few more common solutions for "hybrid" apps, which use some pages as a SPA. That said, it's not that bad once you've got it setup. I like that Rails offers a solution like import maps, but I do also wish there were better core functionality for using some kind of package manager.
Like the redis analogy: Whether or not you need Redis, there are good defaults and very good 'third party' solutions for background jobs (or caching). You don't even need Redis is many cases, but it's easy to grow into.
If there is no need for the level of reactivity that is on the level of facebook style then everything provided by a simple rails new is enough.
But I would say that you kinda need to think about the UX with simplicity in mind or else everything becomes a blog with React because everything can be forced to look like it needs to be reactive and do a lot of unnecessary stuff.
That was roughly my point - unless there's something wrong in my mental model, a Rails user is someone who trusts Rails to get them a sane and consistent bundled pack of tools so they can skip the choice and get to work. If one is going to choose a different set of tooling later on, that seems to defeat the point of using Rails in the first place.
I was not judging the framework itself, for the record. Just saying that if you go for it, going "vanilla" seems like the only sensible choice.
>when they upgrade major versions, all of the tooling that comes bundled in the box changes.
this does sound like a major con indeed.
It is not needed.
Everything wrong with modern web applications.
Yes!
> and they're all necessary for a modern web application
No! Just as important as understanding the purpose of a tool, is also understanding when a certain tool is a bad fit for a certain project. There are no silver bullets.
That doesnt mean you should rewrite an existing app to a more 'vanilla rails' config. You've already eaten the migration cost.
> Embrace the tools: Each tool on the list (Vite, Tailwind, etc.) exists for a reason, and they're all necessary for a modern web application. Saying there are "too many" is an amateur take on the reality of the ecosystem.
Depends. One can still write production-grade web applications with way less dependencies. You can write a Golang web server with minimal dependencies, keep writing CSS "like a peasant" and perhaps use jQuery in the client-side for some interaction. What's wrong with that? If you hire a strong team of engineers, they will be pleased with such a setup. Perhaps add Makefiles to glue some commands together, and you have a robust setup for years to come.
But some engineers feel that counterproductive. They don't want to learn new things, and stick to what they know (usually JS/TS); they think that a technology like CSS is "too old" and so they need things like Tailwind. Makefiles are not sexy enough, so you add some third-party alternatives.
CSS classes not scoped and starting to leak? You hire more frontend developers and because there is no type system we get critical exceptions? And no automated testing to discover them?
Correctly handling hyphenation of user-generated content? Safari decided to handle audio differently in the latest version and you have no polyfills? iPhone decided to kill the tab because of memory pressure, because someone uploaded an image with exotic properties, and you have no cdn service like fastly image optimiser to handle that? Support for right to left languages such as Arabic? The backend returned a super cryptic response that actually originates from the users private firewall?
a11y requires you to use resizable browser text, and someone is using google translate chrome extension at the same time, and you can’t possibly know how the layout of the page will look like?
Some Samsung devices bypass browser detection completely and you don’t know if the user is on mobile or not? localStorage.setItem will throw an error when the device is low on memory, etc etc…
Once you get to a certain scale of users, even the simplest of tasks become littered with corner cases and odd situations. For smaller scale applications, it is not necessary to have a very wide tool arsenal. But if you are facing a large user-base, you need quite some heavy caliber tools to keep things in check.
Most of the problems of software engineering are not technical, they are social. Web development is simple for a team of 1-10. I love the idea of hand-writing CSS and relying on simple scripts for myself and a few teammates. Unfortunately it doesn't scale to large orgs.
It's not that people don't want to learn.
Modern doesn't mean much.
I don't think the Unix philosophy is universally correct either, but "too many tools" is a complaint without much consequential basis. It's an aesthetic problem not a functional one.
Removing ESLint means... you don't have a linter. It doesn't have an upside. Removing Tailwind means you need to write more verbose CSS. Removing Babel means you have to use older JS idioms for browser compatibility. Etc.
I mean complexity comes from many places, but compared to the 'Unix philosophy' most of these tools are quite large. Obviously, there's quite a bit to learn about the way a *nix OS works, but if you treat tools as small and composable for simpler interfaces it helps a lot.
The web dev example of pub/sub is funny, because chances are if you're using Rails your primary DB (probably Postgres) already has a pub/sub system in or. Or you can just use any RDBMS for your job management system.
Real problems are not caused by tools / problem generating systems but by silly people who fetishize complex tooling for simple jobs. Tooling is chosen not by merit but by hype.
No it isn't.
> they're all necessary for a modern web application
No they aren't.
> Saying there are "too many" is an amateur take
Yikes.
Underemphasized
Responsive networked GUIs are complex.
The trouble with an omakase framework is not just that you have to agree to the initial set of choices but that you have to agree with every subsequent choice that's made, and you have to pull your entire dev team along for the ride. It's a very powerful framework, but the maintainers are generally well-meaning humans who do not possess a crystal ball, and many choices were made that were subsequently discarded. Consequently, my sense is that there are very few vanilla Rails apps in the wild anywhere.
(I'm old enough to remember what it was like to deploy a Rails application pre-Docker: rsyncing or dropping a tarball into a fleet of instances and then `touch`ing the requisite file to get the app server to reset. Docker and k8s bring a lot of pain. It's not worse than that was.)
If this is what you remember, then you remember a very broken setup. Even an “ancient” Capistrano deployment system is better than that.
Honestly, even setting up autoscaling via AMIs isn’t that hard. Docker is in many ways the DevOps equivalent of the JS front end world: excessive complexity, largely motivated by people who have no idea what the alternatives are.
My point is that a lot of devs reach to Docker because they think they need it to do these "hard" things, and they immediately get lost in the complexity of that ecosystem, having never realized that there might be a better way.
Costs a crap ton for what it is, but it is nice.
More than that, I worked for many enterprises that were using Rails but had their own infrastructure conventions and requirements, and were unable or unwilling to explore tools like Capistrano or (later) Heroku.
Well, OK, so you remember a bad setup that was bad for whatever reason. My point is that there's nothing about your remembered system that was inherent to Rails, and there were (and are) tons of ways to deploy that didn't do that (just like any other framework).
Capistrano can do whatever you want it to do, of course, so maybe someone wrote a deployment script that rsynced a tarball, touched a file, etc., to restart a server, but it's not standard. The plain vanilla Cap deploy script, IIRC, does a git pull from your repo to a versioned directory, runs the asset build, and restarts the webserver via signal.
The main issue that, while not unique to Rails, plagued the early interpreted-language webapps I worked on was that the tail end of early CI pipelines didn't spit out a unified binary, just a bag of blessed files. Generating a tarball helped, but you still needed to pair it with some sort of an unpack-and-deploy mechanism in environments that wouldn't or couldn't work with stock cap deploy, like the enterprise. (I maintained CC.rb for several years.) Docker was a big step up IMV because all of the sudden the output could be a relatively standardized binary artifact.
This is fun. We should grab a beer and swap war stories.
Rails has a container-based deployment if you actually need that level of complexity.
Could you elaborate? Doesn't sound like a big deal.
Docker helps with the portability due to it's ubiquitous it is now, but it's not like the vm requirement went away, the docker image still generally runs in a vm in any serious environment, and a lot more attention has to be paid to the vm:docker pairing than the previous hypervisor:vm pairing.
It's all about perspectives, or you really just never had to deal with it.
The happy path ain't a big deal. But think of the unhappy ones:
* What if a server gets rebooted (maybe it crashed) for any reason anywhere in the process. Maybe you lost internet while doing the update. Were you still dropping tarballs? Did the server get it? Did it start with the new version while the other servers are still on the old one?
* What about a broken build (maybe gem problem, maybe migration problem, may other). All your servers are on it, or only one? How do you revert (push an older tarball)
A lot more manual processes. Depends on the tool you had. Good tooling to handle this is more prevalent nowadays.
You push the image again.
> What about a broken build. All your servers are on it, or only one?
The ones you pushed the image are on the new image, the ones you didn't push the image are on the old image.
> How do you revert (push an older tarball)
Yes, exactly, you push the older version.
The command pushes a version into the servers. It does exactly what that says. There's nothing complicated to invent about it.
All the interpreted frameworks use the same semantics, because it works extremely well. It tends to work much better than container orchestration, that's for sure.
> A lot more manual processes.
It's only manual if it's not automated... exactly like creating a container, by the way.
> What if a server gets rebooted
Then the rsync/scp would fail and I would notice it in deployment logs. Or it should be straightforward to monitor current version across a fleet of baremetal.
> Maybe you lost internet while doing the update
True, but even Ansible recommends running a controller closer to target machines.
> What about a broken build
That's what tests are for.
> maybe migration problem
That's trickier, but unrelated to deployment method.
> How do you revert (push an older tarball)
By... pushing an older tarball?
But also, that kind of power needs a degree of restraint. You can do those things, but that means that it's on your team to prevent that one bored dev or that one guy who's just joined from a company who did things a different way from their instictive needs to add in new frameworks without a damn good reason.
Both are reasonable answers. It makes people happy to work on their 3-D printers. They love tinkering with them, like printing new braces, holders, parts, etc. The love tuning them. They love finding the perfect filament storage system. That's the hobby. The 3-D printer itself.
I was buying a 3-D printer to make parts. When I realized that I didn't want another hobby, a whole bunch of printer options fell off the table. I wound up choosing a printer that would pretty much work acceptably, once assembled. I have printed stuff with the printer, but I guessed right. At no time do I ever look at the printer as anything more than a tool to get something else done.
From my perspective, it feels like a lot of the JavaScript community falls into the former category. Their JavaScript environment is beautifully incomplete. It must be perfected. They tinker with the works to get the perfect packaging and build process. Bits and parts are changed out, re-worked, or re-written. I think the fact the language invites edge-cases also gives plenty of fodder for new ideas.
I'm a tool user, and that's what I liked about straight-up rails. It did a good job, was faster to develop on than enterprise Java, and the end-product was understandable. Rails and Ruby weren't my projects. The application I was working on was my project.
There's a reason it didn't really get the popularity the other frameworks got.
Seems like wycats is interested renewing his Ember work as of late.
I recall evaluating Ember right around the time they switched from their last pretelease of I think 1.0 and suddenly all the documentation was either gone or out of date and not applicable. I ended up going with AngularJS (1.23 maybe?) and didn't look back until I went to work somewhere that used ember exclusively. It was far less pleasant to use than anything else I had been using up to that point except maybe Backbone.
There's been a few additions to the JS core APIs like webgpu and a few others, but all of them have been extremely niche. There's not much that's been added since 2016 or so that you couldn't pick up in a heartbeat, so it really boils down to the frameworks themselves. Ember lost to AngularJS, then Angular and React.
Circa 2010 those people who were so successful with Ruby had come to the conclusion that they couldn't sell RoR apps anymore so instead they were struggling with Angular -- not to do anything they couldn't with do Rails but rather they though customers demanded applications that looked like Angular applications.
React was a big hit because it was an "Angular" which people could actually deliver working applications with. Its strength I think it is that it addressed certain concerns but left other ones unaddressed such as the theory of async comm. If there is a simple mapping between the state of the application and the state that is represented in the React tree life is great but I look back at the applications I was writing in 2006 and it still looks like a regression.
What I like about it is that I can draw absolutely anything I can imagine with it, even 3-d virtual worlds
https://aframe.io/
Vue has a model which is closer to my mental model of web forms with first-class lists but I can see how to get into "you can't get here from there" situations.
I see the problem React solving is "how to compose an application out of components" and compared to WPF, JavaFX, and such, it's dramatically simpler, it's like a missing chapter out of Graham's On Lisp
Basically, if Ember.js used abstractions that were better for, say, extremely complex applications, it was dead in the water, because most applications make their library decisions when they are small and relatively straightforward. The market for javascript top-to-bottom rewrites of extremely complex apps (where something with those more complicated abstractions shine) wasn't really large enough for it to become dominant.
I also found it difficult to reason with, even though I'm an experienced Rails developer used to spooky action at a distance in the framework. Something about troubleshooting on the frontend really made it more difficult.
Edit: and yes, as you said, it came from Facebook, so it wasn't just a solo developer's grad project; it had a large amount of support right out of the gate.
I am not a UI developer and just needed to understand/debug something, it was not easy at all.
React could be introduced only where it was needed, but Emberjs really wanted to be everywhere and in control of everything.
Compare this to the Ruby ecosystem, where every framework (including Rails) uses Rack, which means that all the frameworks compose together, if that's how you'd like to modularize your monolith. Or the other ecosystem known for its preference for libraries over frameworks, Go, where everything is standardized around http.Handler, so whatever you pick is basically guaranteed to compose.
And it's not just the lack of good overall frameworks, it's the general lack of good defaults for libraries in Node-land. Among the most popular ORMs/query builders over the years there are some surprising omissions, with Knex not supporting connection pinning or Prism not doing database joins by default for a long time.
The problems people solve with JS are different from the ones solved with Rails. Which is why the frameworks look different.
But it doesn’t. Rails is not just a full-stack framework. It’s the entire ecosystem of gems that magically just work together. What JS has is like the Temu version of Rails.
And it’s not like I’m not familiar with JS/Node, it’s the ecosystem I’ve spent the most time over the last 15 years. I’ve just seen so much wasted engineering effort in that time. Not sure what the exact multiplier is, but gut feeling says you’d typically need at least 2x the amount of engineers when using Node over Rails.
> Every Monday a scheduled GitHub Action workflow triggers an automated pull request, which bumps our Rails version to the latest commit on the Rails main branch for that day.
https://github.blog/engineering/building-github-with-ruby-an...
this is a common problem in any complex codebase that has a culture of using third party dependencies to solve small problems. you see this conversation all the time with modern frontend development and the resulting dependency tree you get with npm etc....
... even ten years ago, it felt pretty dated. Has Rails grown some framework-supported tooling for web apps yet, or is that the utility we're talking about?
> Then again reinventing wheels is the JS way of life.
There's some truth to this. The underlying notion is "how much computation do you do server-side vs. client-side," and because browsers don't run every possible language, the shortest path to client-side behavior is in JS. So there's a lot of wheel-reinvention in that sense.
(I do see the notion of writing the code once to run in either context wax and wane. boardgame.io is a JavaScript framework for writing turn-based stateful games; it uses a specific authorship pattern to run the core behavior library both server and client-side, so clients can responsively predict what will happen while the server steps through the rules and updates the game state).
Rails is amazing compared to NextJS or Express + React for me. Getting a lot more done. Writing a lot less code. The Rails ecosystem is great for doing a SaaS + modern content site/app.
I was away from Rails with full stack JS since before the pandemic.
I don’t think that much has changed with Rails since like Rails 4 or 5.
Maybe this is a recency bias, but for my own work or any work where I can dictate or influence the tech stack of a modern web app, I’m sticking with Rails/Laravel and React or Svelte when modern frontend/views are needed.
I don’t think Rails or Laravel should even focus on views that much any more in Ruby/PHP.
I get the best of all worlds now and I don’t hate JS any more. In fact I have sort of fallen in love with React as well now that it is only doing what it should do and I want to learn Svelte.
In my opinion Rails 8 + Intertia.js + React so much less "reinventing the wheel" (especially if you use shadcn components).
I think the problem here is a disconnect of assumptions. Stimulus isn't meant to be an alternative to React.
If your app is (tens of) thousands of lines of JS, and that is all you know a web app to be, then React may be a sensible, battle-tested approach for you.
But if all you need is a few dozen lines of JS to polish the UX of an overwhelmingly server-side app, then Stimulus is a neat way to encapsulate and surface it when desired. In Phoenix, it slots nicely between static HTML views and dynamic LiveViews.
I don't think anyone has ever suggested you should use Stimulus to try to replicate a SPA, and I imagine you'd have a very bad time if you tried.
Unless you work 100% alone (and for a smallish project) hotwire leads to a real mess nobody can work on way before anything else I've ever seen in my life.
Didn't try the whole Turbo/Hotwire thing though. I usually use Vue for complex pages / need of state.
I've used turbo/stimulus/hotwire. It's best suited for STATELESS interactions withe the browser/web page. The problem is not all desired user experiences and use cases are stateless. And the ecosystem for hotwire is a minuscule fraction of all the other popular js frameworks.
If you're searching for inventory available its perfect. However if you want to update one thing based on the most recently touched input it becomes more complicated and in all honesty more trouble that it's worth.
Honestly if you're a solo Rails dev, use whatever you want. However the React ecosystem, and really all of the other popular JS ecosystems (vue, ), are very strong and you have so many available options. Stimulus is 2 steps back from jQuery, it inverted the Event delegation pattern. No one else outside of the rails community is using it.
If your page can be written with it's state being "reasonably" delegated to one of these two, hotwire is _all you need_. (To be clear, it's more common that you're just doing a bunch of work to duplicate state that already exists in the database/on the server, or handled natively by the browser, and by "delegate" I mean don't-duplicate-for-no-good-reason.)
There are many (but fewer than those who "don't get" hotwire believe) cases where it's more of a headache to delegate state to A or B. In which case you should absolutely pull in react/vue/<insert_js_framework>/etc. My go-to is: https://github.com/skryukov/turbo-mount + react because it minimizes it's footprint on the "omakase-ness" of your rails app.
The fact people can't escape JavaScript doesn't stop people from being JS haters.
It just creates more of them.
The nice thing about stimulus is that it binds the pages I'm making to the javascript. It's all easy to find.
90% of what I want react for is to update just part of the page. This is simple with Hotwire now. There is no added marshalling/unmarshalling of json -- just regular crud requests the same as everywhere else. There is no second programming language. There is no added toolchain.
Adding in Stimulus and I can do most of the other things I've been wanting to do -- like modifying dropdowns.
The one place I can see React perhaps being better is when something happens on the page and I don't talk to the server. For most of my business applications, this doesn't come up as much. But say I was organizing a schedule, only to submit it to the server at the very end, React might be better at dragging things around, labelling them, then one big update at the end. Maybe it's easy in Hotwire also, I don't know yet.
I am maintaining a Rails app with Vite + Interia + Vue, and it's many times easier to manage, develop, especially when working with LLMs that haven't been trained on DHH's new frontend experiments du jour.
Funny you should list those out. JS Import Maps (https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...) are literally an industry standard while Inertia and Vite are decidedly NOT standards in any way, shape, or form.
Decidedly, Import Maps are not used as a standard for dependency management in the web dev industry.
These discussions are pointless and I'm a little fed up with them. As another commenter has pointed out, this exact same article (with the exact same conversational style) has appeared for at least 10 years, though I'd push it to 15-20. Write something new...BUILD something new...but for god sake's stop reiterating the same point because it's SO. BORING.
I did work on greenfield Rails apps but they were API only “microservices” so none of this FE stuff was needed.
In any nontrivial company, the Rails homegrown FE solutions are ignored entirely because you can’t hire Hotwire devs but you can hire plenty of React/Vue devs.
Also, the Rails “FE” stack has changed plenty and it’s also hard to keep up with it (remember CoffeeScript?), is poorly documented beyond the trivial hello world and like I said, has absolutely no mindshare.
So these discussions are entirely disconnected from the real world.
I have no idea how one manages to be a HN reader and come out with a proclamation like "there are no greenfield projects left".
Neither venerable monoliths nor Fortune 500 companies represent the mean website. You're looking at highly visible outliers and ignoring the forest for the few redwoods that poke above the rest.
The care that's put into ensuring `rails new` creates something sane and basically production ready is exemplary. It's the missing middle between Hello World and terse API autodocs that so many tools just lack. Whether one uses Rails or not, this is something to emulate, not glibly denigrate.
I recently had to rescue a complex web-framework based system that was an absolute clusterfuck full of basic programming mistakes - the most glaring of which was a complete lack of database transactions in the node backend - but what it did have was every fashionable bell and whistle installed, and extensive reliance on the AWS ecosystem, as if it was designed for millions of concurrent users, whereas a single simple VM running about about 1% load would have done the trick.
And yet all this complexity actually did very little - a simple Rails-based-app would have done it all, at a fraction of the complexity, with far fewer dependencies.
We hired one of the very few people that just used SSR.
ever since i started using frontend frameworks for websites, the backend has become trivially simple. so simple that i have been able to reuse the same backend for all my websites built since. most websites do not need more than CRUD on the backend. and even for those that do need more backend logic, separating front and backend makes both parts easier to develop. they don't get entangled, and i can make drastic changes in either part without breaking the other.
frontend frameworks allow me to think of the frontend as an independent client application that runs in the browser. instead of having a complex application that displays here but runs over there, i have two simple applications, one that runs on the server and one that runs in the browser.
using a frontend framework makes development feel like writing a desktop application. i don't have to consider network latency, except to load and update data. but that can happen in the background. it doesn't affect the UI. it makes me think about loading data from the server efficiently. it allows me to preload data in the background. it allows me to cache it so that when the user switches between different views, the data doesn't have to be reloaded, yet it can still be updated.
you can do this with a server framework only too. but getting that working smoothly across multiple page loads is a lot more complex than having all views that share data in a single page application.
And there begin the problems. Do you really want to expose a full CRUD API, or are there consistency/security rules you want to enforce? That's cool, but makes API design a little more challenging and frontend development a little more frustrating. SSR eliminates a lot of these problems, and for many types of software, it's quite sufficient.
For a lot of software, it doesn't make that much sense of course, e.g. if you need clients for multiple platforms.
That's the kind of conversation I wanted to have with the candidates that went for that architecture.
fair point, however i don't see that as a drawback. the security/consistency rules you want anyways. and an API makes it easier to enforce them and not allow people working on the frontend to get around them because they have direct access to the database. in difference to what you said, i believe the benefit of a rich client is that it doesn't have full access to the database, but only the access the API provides.
i also don't feel that it makes frontend work more frustrating, on the contrary, it means i don't have to worry about access control in the frontend because the backend is supposed to take care of that.
to give an example: if i want to limit the size of the text field, i have to implement checks twice, once in the html/js, to help the user, and once in the database access to make sure the user didn't cheat. i have to do that regardless of whether front and backend are separated or not. it doesn't make a difference. but the separation ensures that the frontend code can't get around the limit.
where it does get frustrating is when you have different teams that have to communicate and agree. but the problem there is the team size, not the architecture.
this subthread started out with the claim that small teams don't need the complexity of frontend/backend separation introduces. that's where i disagree. the complexity shouldn't be an issue. as i said, i find it reduces complexity. a small team also won't have the communication problems when disagreements arise over the API. they can handle that like disagreements over the class hierarchy or datastructures or whatever. you talk about it, make a decision and everyone is on the same page on what to implement.
That's the kind of conversation I wanted to have with the candidates that went for that architecture
are you still hiring? :-)
and you still have to enforce that business logic in the backend as well.
React has been very stable throughout its life time. You can run 10yo react code in v19x without issues.
When you are building a data browser, you should use web tools.
Easier just to start with it from the beginning. Assuming you're a full stack / front end guy of course, or else I get the appeal of html only.
In most industries, your clients won't care if the software relies on an ultra scalable architecture split in microservices or a monolith + PostgreSQL.
I’m finally at the age where productivity is infinitely more important than anything else.
I have ported a chunk of my likely last full stack JS project over to Rails with AI vibe coding everything as a reference for me to redo it again with AI but not vibe coding.
Absolutely amazing work. About 40% of that NextJS app was vibe coded and the process of undoing the excessive and verbose code was depressing me.
The Ruby and Rails code is simple and understandable and a fraction of the lines of code.
Last sentence exactly. I am using IntertiaJS for some of the frontend and I finally don’t dislike JS any more. React is amazing when it’s only a view library.
You probably want to automate the infra creation (so Terraform, Pulumi, CDK...), you want to automate building (so GitHub Actions, Jenkins, Bitbucket Pipelines, GitLab CI...) and artifact storage (so Nexus, Arti, ECR, GHCR...), you want to automate deployment (so Argo, Flux, Helm, Kustomize...), you want to automate monitoring (so Prom stack, Datadog, many APMs, Splunk, Graylog, ELK... could easily name a dozen more).
Each part of the stack can easily bring a dozen different tools. I work in SRE and I use at least 40-50 tools for a mid-sized project. And this is "normal" :)
Whereas churn in web-dev seems self-inflected.. devops practitioners don't actually create vendor/platform fragmentation, they just deal with it after someone else wants the new trendy thing. Devops is remarkably standardized anyway even in the face of that, as evidenced by the fact that there's going to be a terraform'y way to work with almost all of the vendors/platforms you mentioned. And mentioning 20 ways to use kubernetes glosses over the fact that.. it's all just kubernetes! Another amazing example of standardization and a clear "winner" for tech stack in niche.
Not all of those tools do identical jobs but there's a ton of overlap within them and they all have idiosyncracies.
That said you can avoid it. I wrote a website using Fresh (https://fresh.deno.dev/) and that was the only thing I needed. Incredibly simple compared to the usual Node/Webpack mess. Plus you're writing in Typescript, and can use TSX.
I probably would set up ESLint if multiple people were working on the project. But you can definitely start without anything else.
Take a look at ads on rails newsletters and how many of them are professional services to upgrade your rails app.
So many gems are also still built on sprockets — even when you want to use the “rails” way, you are stuck now with a hodgepodge of JS anyways.
It’s a mess — maybe one day we’ll get it fixed, but don’t pretend it’s not partially rails fault as well.
I still use and love Django, and don't bother with that stuff. Django Rest Framework was another distraction.
Did it work well? Any lessons that others should know of?
I've built dev tooling for local deployment management and release automation and those have worked well, but the code generation piece is something I'm curious about.
Meanwhile Rails is becoming easier and easier to run complex apps with much smaller teams.
It’s usually the lack of non-React knowledge to know what does or doesn’t require React.
I don't understand the aversion to actually writing HTML and CSS!
If you went head-to-head with Rails on a slightly complex project with say shadcn/ui, Convex DB, and TanStack Start, I guarantee you, the TypeScript app will be much simpler and give you more power than Rails, especially when building the UI. And to top it off, you will have strong typing everywhere -- from the DB schema to the URL routes.
And bonus, deployment is simple. ConvexDB already takes care of the backend and the frontend could be deployed to something like Cloudflare Pages.
Go build a web analytics tool with that
The market for these new breed of frameworks is not huge companies with crazy scaling needs but freelancers and your very early stage startups who haven't even found a product market fit since they are starting new they don't have anything to loose with newer stuff and chances are that newer stuff also helps them do more quickly like I haven't used convex but on it's marketing page it does mention a lot and same for other frameworks like pocketbase or SvelteKit combined with a db etc. Like always there is no silver bullet and every stack can seem "random"
Funny enough there is another library which checks if it is even https://www.npmjs.com/package/is-even
You don't need to think about React Refresh or babel or typescript, it's all handled by vite. I've never even seen a .babelrc file. And why does the author add husky?
Like, if you want to criticize JS fine, but chose valid criticisms. This just sounds like the author hasn't actually used modern js.
I guess I should draw the rest of the owl.
I wrote that post about a similar sentiment - that lag is a feature instead of a bug in Rails framework development.
There were talks on twitter about how the old days of using PHP and Perl with FTP just works.
- you wouldnt use vite then also add next or remix
- if you're using vite, next.js, etc. you're not going to need to add nor configure babel
- vite, next.js, etc. starters come with pretty much all of these separate things he mentions included. typescript, prettier, eslint, tailwind, react etc. You know, like a batteries included framework.
You could do the exact same breakdown describing the pieces of rails you need to learn to accomplish the same things, just because they are more separated libs in the front-end doesn't mean the problem is simpler if you solve it with rails' chosen tools vs the popular npm solutions.
But I couldn't get JRuby to package reliably. I'd fix the issues, it would work for a while, and then something would change.
Oh... because I wasn't doing it right. I have to rework a bunch of dependencies. And after a while, it breaks again. Why? Oh... I wasn't doing it right, I should be using this middleware instead...
So I said I'm done mucking around with JRuby. When I said this, I was told at RailsConf that was doing it wrong, and by implication, irresponsible with my clients' applications. That was I setting everything up for failure. Yet the applications that were working just fine on C Ruby. (I don't really hear much about JRuby any more - but I haven't been part of that world since George "strategery" Bush was president.)
And this was the shtick for conference speakers and YouTubers. You're doing it wrong. Do it this way to do it right. You're using Controllers wrong. They should be fat. They should be thin. They should be big boned. You should never use models. You should only use models. You should sit on two chairs and pair program with yourself when you develop. Only drink water when writing tests.... etc. etc. etc.
This left a bad taste in my mouth in what otherwise was a great community. I felt like a lot of the community wanted to do build great applications, quickly, cost-effectively, and with high quality. But that same impetus could be manipulated by folks in a way that's unhelpful. THAT part of Ruby I don't miss. RailsConf in Portland, eating VooDoo doughnuts, talking shop with other folks? That I miss.
I any differences in workflow I see seem to be down to opinion rather than some difficiency in the technology.
No, just no. Or maybe it depends. But if you want to provide a lovely, modern, interactive frontend, you can't just blindly ignore what evolved on the frontend ecosystem for the sake of your purity. It's arrogant and dismisses all the people who love to craft enjoyable frontends.
Following some thoughts about how to merge Rails and modern frontend approaches and how Inertia finally solved that question for me.
--
I consider myself more frontend focused but I have a deep love for Rails and some advanced experience, for sure less than in frontend though.
I tried hard following the route of hotwire, stimulus and friends knowing that DHH and the rest of the community loves those JS patterns.
Creating reusable stuff, cresting just a little bit more complex components, sharing those components through the UI.. it's just horrible cumbersome, repetitive and far, far away from all those best practices and patterns we've developed in the frontend.
I tried creating a diff viewer with comment functionality with stimulus. It worked, I was kind of proud but it was cumbersome the define components and share functionality. Maintainable? No way.
Then I wanted to create a double list where you can drag items from left to right. It was the hell to include css, js, manage the hierarchy and then I just gave up. I was demotivated by the constant nagging of my brain how much more simple this would have been with a single, simple react/vue component.
Then I went the wrong route: Rails API plus React. That's just giving up on most of what Rails gives you and I wasted ton of my time creating an additional auth layer on top of the session that Rails would give me. And then the horrible duplication of your state. One in Rails and then the same stuff in React. The same nagging in my brain now told me: That's wrong.
And then I found the holy grail of modern Rails development: Inertia.js. I heard about it very often but never at the right time. So I forced myself to try it out.
And here I am: I use Rails with Inertia Rails. I have the full pleasure of Rails but I can create React components that represent any page I like to write in React. Inertia will serialize and pass in the data from my controller. So no state. Just pure UI building.
If you love Rails and the frontend: Try out Inertia. It feels like I'm using the best of both worlds. The layer inertia creates is very shallow and optional. So the risk is low.
I think that's still pretty ridiculous though.
I find that Rails+vite is a pretty nice sweet spot that really does just work. It's far far better than trying to use Rails with that "webpacker" chain or anything like that. i like that vite can do my CSS and my JS preprocessing needs, so it's just ONE thing, vite, and I'm set.
(Hypothetically you can use some light weight NPM dependencies with "just Rails" (really a weird take on importmaps, not "just rails"), but unless it's ultra simple it gets just ridiculous very quickly. Vite does not. I think the "no need for any real npm dependencies or other preprocesing of your JS, or CSS" dhh take is a weird one. Fortunately everything still works great if you agree with me.
(sorry, it was just too obvious)
vite is actually stable and good, js ecosystem has chilled out
these articles do not hold much weight anymore
If I'm making a typical website, all I'm using is a few PHP files, a single CSS file and maybe some JavaScript.
There are no build steps. No minification. No compilation. No frameworks.
I just can't understand even using Rails for web dev.
And they look at me like I'm the lunatic when I tell them their 3 text fields 2 buttons "app" is over-engineered and needs no build step.
Some people are building real web applications, not PHP toys. I get not wanting to keep up with the latest JS insanity, but simple MVC frameworks are popular for a reason.
Rails apps are rare and getting replaced. Most web apps are static builds where the tools listed are not used all at once and largely irrelevant outside the dev environment.
> John runs a single command. The app boots instantly, working forms, instant loading times, blazing fast navigation.
Same with node? npm run build && npm start
The front-end dev space feels like a cacophony of people all blurting out the same over-engineered stack. If your app is a few lists, a chart, and a form... Does it _reaaallly_ need React?
37signals is afterall running multiple successful products with Rails, and one of them is an email client.
I liked this video, maybe you will to: https://youtu.be/mTa2d3OLXhg?si=nhqGO4lPaAcP0mdm&t=3000
I don't agree with everything DHH says, but I think he has a really good point.
If your app is that simple you don't even need Rails.
In my experience, everything starts that simple. But then time passes, team members rotate, and... your PM keeps asking to add more and more features... And that's when the "simplicity of hotwire" becomes a nightmare to maintain. And guess what, the next dev that comes to the project will hate all the hotwire crap, and whoever built it.
It's easier to make a simple list and a form with React/vue/svelte even if it seems overkill at first, because when things get more difficult you already have the big guns. If you start with the tools to build simple, well.... wish your project stays that simple forever, or that you're given enough time to rewrite everything.
> 37signals is afterall running multiple successful products with Rails, and one of them is an email client.
These applications may be a successful product, despite of hotwire, but they're not a good example of anything. They feel like shit to me (using them from Europe). And again, the main problem is not the end result but the maintenance. If there's anything we've got from all of this mess, is that implementing UIs as "components" are the best idea in the last 10 years.
Stop beating the dead horse of variables interpolated in templates. It just doesn't work (unless you work alone).
—-
I love Rails but disagree. Using InertiaJS and React, Vue, or Svelte for some of the front end/views makes too much sense. The new Rails Way should be optionally allowing this.
You'd be surprised what kind of far worse junk than anything we're talking about can scale the same or better and is ergonomic to another type of dev. This is all just bikeshedding.
Of course Hey is still young... But I'm pretty sure you also know that they have Basecamp with 3M+ users. I mentioned Hey because I think it's a great example of sth more than lists/forms.
At some point, the business cannot be just one app or one tech stack. More devs will come aboard that disagree with the chosen tools and for very good reasons. You must work with the devs you have and the expertise they bring. Only the most out of touch CTO would avoid sunsetting legacy apps. There's the business side concerned with functionality, and then there's the hiring side concerned with implementation details. Both are key to getting the best devs and the best results.
Wait until you find out how many YC startups use Rails...
Or how big Shopify is. Or how many other large companies use it. And how many startups use it but just don't talk about it because it isn't cool anymore.
Sure it does. If you're not using Vite, how are you bundling? Oh, you're not bundling? I guess that means you're not using TypeScript? Interesting, how do you catch errors? Oh you just let things crash in production? How do other engineers understand the intent behind your code? Oh they don't I see. If you're not using React, what are you using? Vanilla JS? Have you considered that it's a statistical fact that every single person who has said "I don't need React, it's just a big complex mess, I'll just invent it myself" ends up creating an informally-specified, bug-ridden, slow implementation of half of React? Oh you don't use Prettier? OK, how are you formatting your code? Oh you're not, it's just a giant mess? Oh you're not using ESLint, interesting, how do you keep code consistent across your team? Oh that's not a concern? Hm.
Almost every technology in the article exists for good reason, and solves a real issue[1]. Maybe not an issue the author has encountered, but the author shows no understanding of the issues they are solving, and the final "punchline" implies that anyone could just toss all this tech out and improve their developer experience. "Learn the rules before you break them" applies here.
This is an uncurious article which mocks at abstractions rather than taking the effort to understand why they exist.
[1]: OK, I do think some abstractions are more trouble than their worth. But why did the author choose all the reasonable ones, like React? Why not dunk on Angular, I mean come on!
Most projects are very simple CRUD apps anyways.
But in reality if you're using hotwire you can get away with almost no JavaScript at all comparatively. That's why stimulus is in vanilla js generally, it's meant for sprinkling behavior onto the dom vs controlling the dom.
So if you don't have a js framework that needs to control the whole Dom and doesn't need a gigantic optimization step or tree shaking or typescript or whatever, you can get away with a whole lot less than it you embraced those frameworks that _do_ want to own the dom wholesale.
If static types are so fundamental for you, I'd suggest skipping Rails entirely and reading other content.
You write code differently, and you write tests. Rigorously testing business logic also has the nice side effect of catching type errors. "crash at runtime" in the real world means "crash in your tests". I've written a tonne of Ruby and it's simply not an issue
Plenty of businesses have been built on the back of dynamic languages. Nubank runs their somewhat critical business on millions of lines of gasp dynamic Clojure
> ..ends up creating an informally-specified, bug-ridden, slow implementation of half of React?
VS Code is written with custom JavaScript
Obsidian is written with custom JavaScript
Here's one reason to do it: the churn in these ecosystems is insane. Imagine writing a huge app in backbonejs back in the day when it was popular.. and then subsequently abandoned as people moved on to the new better way. That's an existential threat to your business if you're a small team. Even a big team takes a huge hit there
Vue2 to Vue3 was a shitshow. AngularJS -> Angular 2..
I'm still annoyed at React Query straight up deleting the documentation for the version a project I was on was using. Rails still has their docs up for the version released in 2009? The JS community just doesn't care about longevity
What happens when the React team decides "oh well actually WASM is the way forward" and redoes everything.. or maybe Svelte ends up taking over 4 years from now? Or hell if they even just evolve the framework in a direction that isn't in line with with what you want out of it
That's a real problem... and it's largely cultural and not technical which makes it even worse.