Summarized using AI

The Front-end is Omakase

Cameron Dutro • July 10, 2025 • Philadelphia, PA • Talk

The Front-end is Omakase: Bringing Rails Philosophy to Front-end Development

Cameron Dutro's talk at RailsConf 2025 examines the divergence between the strongly opinionated, 'omakase' approach of Ruby on Rails on the backend and the much more flexible, 'okonomi' approach that has come to dominate the Rails front-end ecosystem. Borrowing from DHH’s classic blog post, Dutro explores whether Rails would benefit from more opinionated defaults on the front-end, similar to its backend philosophy.

Main Topic

  • The concept of 'omakase' in software: trusting experienced developers to provide defaults and conventions, as Rails traditionally does.
  • Contrasting front-end's abundance of choices ("okonomi") with Rails' history of strong conventions and minimal configuration ("omakase").

Key Points

  • The Value of Constraints
    • Dutro opens with personal and historical anecdotes (his open-source contributions spiking when life was more constrained; the Concorde and Apollo 11 computer as examples of engineering success under constraints).
    • He invokes Leonardo da Vinci’s idea that creativity thrives with constraints and links it to Rails’ philosophy.
  • Rails' Omakase Philosophy
    • Rails has always made many decisions for developers (e.g., folder structure, Active Record, Minitest) which has contributed to its productivity and ease of use.
    • Other development communities (like Deno) are now recognizing the effectiveness of opinionated, batteries-included frameworks.
  • The Fragmented State of the Front-end
    • Front-end development currently demands many technology choices: JS package manager, bundler, CSS library, TypeScript/Javascript, and various frameworks.
    • The number of combinations (over 16,000) leads to decision fatigue and interoperability issues.
    • JavaScript-heavy setups bring complexity, poor debugging, bloated dependencies, and performance issues.
  • The Evolution of Front-end Tooling in Rails
    • The Rails asset story moved from static files to Sprockets, then to Webpacker, followed by a proliferation of options (CSS bundling, JS bundling, import maps), resulting in less cohesion.
  • Proposed Omakase Front-end Stack
    • Dutro offers strong recommendations for Rails defaults to restore omakase on the front-end:
    • Use NPM as the package manager
    • Use a build system (specifically Vite for bundling and development experience)
    • Favor PostCSS for CSS processing
    • Use TypeScript
    • Adopt BEM methodology for CSS structure
    • Rely on web components, Stimulus, and Hotwire for interactivity—not heavy JS frameworks
    • Avoid import maps, Webpack, and adopting JS frameworks like React unless essential
  • Performance and Simplicity
    • Warns against frontend bloat: cites studies and anecdotes about excessive JavaScript payloads hurting the end-user experience.
    • Stresses that most applications do not need a heavy JavaScript framework.

Illustrative Examples

  • Personal productivity spikes under tighter time constraints, paralleling how Rails constraints lead to productivity.
  • Engineering projects (Concorde, Apollo 11) succeeding within strict limitations.
  • Anecdotes and tweets highlighting the difference between Rails and JavaScript communities regarding tooling and conventions.

New Tools and Innovations

  • Dutro introduces 'velour', a work-in-progress Rails generator promoting an omakase front-end stack (Vite, PostCSS, TypeScript, NPM).
  • Mentions ongoing work on a Ruby-based front-end reactive framework (Wisdom).

Q&A and Conclusions

  • Emphasizes practicality: the proposed stack works cohesively, reduces complexity, and supports maintainability.
  • Concludes that a Rails omakase front-end would hugely benefit productivity for both new and experienced developers, reducing decision fatigue and fostering a better developer experience.

The Front-end is Omakase
Cameron Dutro • Philadelphia, PA • Talk

Date: July 10, 2025
Published: July 23, 2025
Announced: unknown

"Rails is omakase." DHH's classic 2012 blog post is still great reading in 2025. Here's a quote from the article that sums up his main point:

"A team of chefs picked out the ingredients, designed the APIs, and arranged the order of consumption on your behalf according to their idea of what would make for a tasty full-stack framework."

Right! And we have all benefitted enormously from the Rails core team sharing those tastes with the rest of us. The ingredients and API design decisions he's referring to fit the shape of a great deal of the web applications we might want to build. Just as we trust the omakase chef to serve a great unagi and sake pairing, we lean on the years of industry experience baked into Rails to build web applications with fewer resources.

If Rails and the Rails philosophy are omakase, the front-end world is the opposite: "okonomi," meaning "choosing what to order." Rather than picking a set of technologies, smart defaults, and conventions on your behalf, most front-end frameworks and tools expect the developer to cobble together a bunch of tools that were not necessarily designed to work with one another. The decision points are endless: Typescript or Javascript? Vite, webpack, or importmaps? SASS or Less? PostCSS or dart-sass? Tailwind, Bootstrap, or Bulma? BEM, SMACSS, OOCSS, CUBE, or HECS? Maybe CSS modules? And what about React, Vue, Angular, Svelte, or HTMX? The list goes on and on.

For understandable reasons, Rails has gradually retracted its opinions around front-end development over the last 10 years. In practice this has meant the Rails front-end is much less omakase and much more okonomi than the rest of the framework. Need a Javascript bundler? Bring your own. Want to use Typescript? Configure it yourself. While at first glance the high degree of flexibility might seem freeing, it's quite contrary to how Rails was originally designed. As Leonardo Da Vinci said, "Art lives from constraints and dies from freedom." The constraints Rails places on its developers are, somewhat counterintuitively, the same things that make it such a productive framework.

In my opinion, Rails needs an omakase front-end. We need a set of strong front-end opinions like we have on the back-end.

During my talk, I'd like to share my opinions for configuring the front-end of a Rails application, and provide a look at the libraries, configurations, and tools I've found to be the most productive. The talk will include a brief history of front-end tooling in Rails, what we've learned along the way, and what a more opinionated future could look like. I'll introduce a Rails generator I'm working on that configures a fully-baked and opinionated front-end setup - like Jumpstart or Bullet Train, but specifically for the front-end. I'd like to finish up by touching on future innovations like rendering ViewComponents in the browser.

So, why am I qualified to give this talk? I work on an open-source design system for a large company that runs a number of complex Rails apps. I've been around for most of the big front-end shifts in Rails, including the introduction of the asset pipeline, CoffeeScript, webpacker, and now js/cssbundling, importmaps, and ViewComponent. I've written code using all of these tools, and now my design systems work is giving me an even broader look at the front-end ecosystem. I recently re-wrote the documentation for getting started with our gems and Javascript packages, including a guide for adding it to a Rails app. I wanted to be thorough, so I covered configuring every tool supported by cssbundling-rails and jsbundling-rails, as well as Sprockets, vite, and importmaps. It was... a lot. Imagine how overwhelming all these choices must be for a beginner coming to Rails for the first time. Hell, I barely have a handle them, and I've been in the industry for 15 years.

RailsConf 2025

00:00:19.600 for being here uh at the final Rails comp and especially after such an
00:00:24.960 incredibly moving and and wonderful keynote by by Audi. I don't know if a
00:00:31.679 conference talk has ever made me cry, but it did. Um just a wonderful celebration of Rails and of our
00:00:39.040 community. So awesome job, AI. Um show of hands, who attended Rails
00:00:45.280 Comp in 2012 in Austin? Wow, there's not a single hand. Okay.
00:00:53.280 Oh, no. There's one. There's one. Okay. Yeah, 2012 was my first Rails comp. Um,
00:00:58.719 and I actually spoke at that one too about internationalization and for that reason and so many more.
00:01:05.040 It's an absolute honor to be chosen to speak at this the very last RailsCom.
00:01:10.479 Um, so thank you for being here. Thanks for making the Rails community a place that I have wanted to stay a part of for
00:01:16.080 the last 15 years. Um, back in 2012, I had just gotten a
00:01:22.080 new DSLR camera. I took some photos of the conference because I took my camera
00:01:27.119 everywhere because I was so enamored with it. And um, I'm looking through the pictures I took trying to find one that
00:01:33.439 might sort of fit in for this talk. And I found this one.
00:01:38.640 And uh, I didn't know who any of these people were at the time. Um, but they seemed important. So I snapped the
00:01:44.479 picture. Uh, and the thing that strikes me now looking back is just how wet David looks.
00:01:51.439 Like I don't know, did Evan throw a cup of water on him or something? I don't know what happened there. Uh, anyway,
00:01:56.640 it's good times. Um, before I really go into introductions about who I am though, I think by way of introduction,
00:02:03.520 I'd like to share some screenshots of my GitHub contribution history. This is probably how we should all introduce ourselves, right? Um, so take a look at
00:02:11.920 this real quick. 2018. I'm not actually sure how GitHub counts contributions uh
00:02:17.200 if this is commits or what this is. Uh this is 2018 and then in 2019 311 and
00:02:24.000 then a big jump in 2020 603 616 in 2021 and then finally a whopping
00:02:32.000 145 in 2022. And I'm not standing up here trying to say like I'm an amazing open source contributor. I'm just trying
00:02:38.080 to show this interesting data pattern and sort of explain. it'll become clear sort of why I'm talking about this uh in
00:02:43.920 a second. Let's also look at some events in my life that may sort of you know overlay onto this to see what was going
00:02:50.720 on at that time. Um we can also see the delta here. So that's a change of 79 for
00:02:55.760 those first two years a big one at 292 just 13 later and then the last one is a
00:03:01.200 big jump for 429. So what were some things going on in my life? Well, in 2019, my first daughter was born in
00:03:08.319 December. And in 2021, my second daughter was born. And you might be thinking like, that's weird. Shouldn't
00:03:14.239 he have less free time to work on open source? And I was really baffled at this, too. Um, I mean, kids take up so
00:03:21.120 much of your your free time. Um, but I think the pattern is is like relatively obvious here. Um, and you know, you
00:03:28.800 would think that why I firmly believe that the reason for these big contribution spikes is precisely because
00:03:36.400 my time was so constrained. We've talked I think we heard Audi talk about constraints as well. That's one of the
00:03:42.319 big thrusts of this talk is that constraints actually lead to higher productivity. I didn't have a commute
00:03:48.879 anymore back in those days starting in uh 2020 or so um because of the pandemic
00:03:53.920 and um most of my time on holidays and weekends was spent taking care of my kids. Um but you know I would think
00:03:59.920 about my side projects like in the shower and and during breakfast and other times throughout the day and
00:04:05.920 decide exactly what I was going to do next. When I got 30 minutes of free time, I would sit down on my computer
00:04:11.680 and I could actually like really start working on the feature or whatever right away. So, I got better over time at
00:04:18.239 picking tasks that could fit into the time that I had available and at working
00:04:23.360 out the logic in my head before sitting down at my desk. Um, so my open source work time became more focused. It became
00:04:29.919 more deliberate. I was guided by the forcing function of this severely constrained schedule.
00:04:36.400 And I started seeing this sort of um phenomenon in other places too. And it
00:04:41.440 reminded me of this Leonardo da Vinci quote. He said, "Art lives from
00:04:47.199 constraints and dies from freedom." And in my own experience, I've found this to be extremely true. But I also think that
00:04:54.400 history is sort of rife with examples of this as well. Uh so take the conquered
00:05:00.639 supersonic jet. Um conquered was the first and I think only supersonic
00:05:06.639 commercial jet. Um it took decades to build and had to overcome a series of
00:05:12.160 really huge technical obstacles before its first flight. Um one of these challenges was
00:05:18.880 temperature fluctuations. It had to be designed to withstand temperatures ranging from -55° centigrade uh at high
00:05:26.000 altitude to 160° during supersonic flight which required specialized materials design solutions to manage
00:05:33.360 thermal expansion and contraction. It also had to be more fuel efficient.
00:05:39.039 It's uh supersonic flight is significantly more fuel intensive than subsonic flight. Um it had to be more
00:05:46.240 aerodynamic than previous aircraft. It's innovative and iconic droop nose was invented to enhance pilot visibility
00:05:52.960 during landing but presented aerodynamic challenges. Um and its wing design while optimized
00:06:00.960 for high-speed flight made it less efficient for takeoff and landing requiring higher speeds and special
00:06:07.199 handling techniques. The thing is that despite these many engineering challenges, Concrete was
00:06:14.479 built successfully and it flew for years. In fact, I don't think it's an exaggeration to say Concrete was one of
00:06:21.520 the greatest engineering achievements of the last 50 years. And I think that that's largely due to the number of
00:06:27.840 constraints placed on the conquered team, forcing them to focus on the right
00:06:33.680 things. Uh, speaking of engineering greatness, let's take a look at another example of
00:06:38.880 what I would call art or engineering greatness thriving under constraints. And that's the Apollo 11 flight
00:06:44.240 computer. Uh, you've probably seen this photo before. This is Margaret Hamilton
00:06:49.600 standing next to the code that she and her team wrote in the late 1960s. Um the computer system that they had to work
00:06:55.759 with was extremely rudimentary by today's standards. They had 72 kilobytes
00:07:01.039 of memory, not megabytes, kilobytes. Um they actually had to handwave wires
00:07:07.280 for additional storage. There was no product you could buy off the shelf for this. Uh but even that was very limited.
00:07:14.080 The whole thing was programmed on paper punch cards. And it was also in
00:07:19.120 innovative in the sense that it was maybe one of the first systems built that was had built-in fall tolerance. And for that reason, it actually never
00:07:25.199 failed, never had a cat catastrophic failure during flight operations. And I
00:07:30.479 don't know about you, but I have seen apps that use untold numbers of gigabytes of memory that fail all the
00:07:36.160 time. Um, the constraints of the environment and the available technology guided the
00:07:42.720 Apollo development team, I think, by allowing them to focus on specific technical problems and disregard others.
00:07:50.000 In Hamilton's own words, there was no choice but to be pioneers. The things
00:07:55.520 they were doing had never been done before. But while the limitations of Apollo 11's hardware seem like they
00:08:01.759 should have been a barrier to success, I would argue they directly led to success, more constraints lead to
00:08:08.960 increased focus, and increased focus leads to incredible outcomes. But even
00:08:14.319 if you don't buy the argument that constraints equal achievement, we tend
00:08:19.520 to think of achievement as more impressive when the goal seems impossible. And I think that
00:08:25.440 psychologically many of us are drawn to doing hard things because we know that if we
00:08:31.360 succeed we will really have done something. Okay. So what does all of this have to
00:08:36.800 do with Rails? So around my first Rails comp in 2012 uh
00:08:42.800 DHH published this seinal blog post. Um show of hands who has read Rails is
00:08:49.839 Omacas on DHH's blog. Yeah, even today I feel like it's one of those extremely
00:08:55.120 well-known and influential blog posts. Uh, it was a big topic of conversation back in the day when it came out. Here
00:09:02.160 is a quote that sums up the main idea. A team of chefs picked out the
00:09:08.399 ingredients, designed the APIs, and arranged the order of consumption on your behalf according to their idea of
00:09:15.760 what would make for a tasty full stack framework. He introduced, I think, many Rails devs to the Japanese concept of
00:09:23.360 omic acid
00:09:30.240 what you eat rather than you deciding it from a menu. For example,
00:09:35.519 um in the case of Rails, omicass means letting the core team decide what to put
00:09:40.560 in the framework such that the whole thing can be used to build an application quickly and easily.
00:09:47.519 Rails is explicitly designed to take away choice. As we've seen, while that
00:09:52.880 might initially sound like a bad thing, it's very much a good thing. It places
00:09:58.000 constraints on you, the developer, and drastically limits the number of decisions you have to make to get up and
00:10:04.080 running. This is one of Rail's biggest and most valuable ideas. Rather than
00:10:09.120 spending time deciding how to configure a library to talk to a database, you just use active record. Active record is
00:10:15.760 a constraint. It might not be perfect, but it's the default and it works most of the time.
00:10:22.480 Just as large temperature fluctuations guided Conquer's engineers toward the lightweight, durable fuselage material
00:10:29.680 for their aircraft, so does active record guide developers toward battle tested database access and persistence
00:10:36.000 patterns for their applications. Let's take a look at a few of the ways that Rails limits decision fatigue
00:10:43.760 through constraints. One of the big ones is folder structure. There's a place for every file. If you
00:10:50.399 don't think this is a big deal, just talk to your favorite React developer.
00:10:56.079 Miniest, there's no need to configure a test framework or bolt it on. Miniest is built right in. It works great. Of
00:11:03.279 course, all the sub frameworks we talked about active record, but there's also other frameworks for performing work in
00:11:08.640 the background, sending email, communicating async with the front end, etc., etc. And of course, maybe some
00:11:16.240 newcomers, Stimulus, JavaScript sprinkles, no need to add any third party libraries, this just works. Uh,
00:11:22.959 Kamal for straightforward deploying, Thruster, this the fast HTTP proxy that
00:11:28.399 came out a few years ago. And then we're also now seeing I think even more innovation or or simplicity rather in
00:11:34.560 the form of SQLite powered um projects like solid Q etc. um a whole new era of
00:11:41.120 simplicity around the database layer that removes the need to run a separate database server.
00:11:48.000 So this batteriesinccluded omocas constraintdriven approach is such
00:11:53.600 an important idea that other frameworks and communities are starting to discover this organically.
00:11:58.800 Um which is surprising to me because it's been there the whole time but it's kind of an unusual I think other communities are now finally starting to
00:12:05.120 get this. Um, this is a tweet I posted a few years ago after listening to an
00:12:10.959 episode of the change log podcast where the authors of the Dino framework, the Dino runtime called uh or a framework
00:12:17.440 rather that's written for Dino called Fresh were going on and on about things like serverside rendering and routing
00:12:23.040 and middleware. And as a Rails dev, it made me just kind of shake my head like
00:12:28.079 we would had this for years, right? Um, I guess we had to go through a cycle or something so the old ideas could become
00:12:33.760 new again. Um, here's Luca Casinado from that episode describing Dino's approach.
00:12:40.399 He says, "One of the core ideas of Dino is to have this whole batteries included runtime and a million other things all
00:12:47.040 in the same binary maintained by the same people with the same opinions to sort of give you a cohesive experience.
00:12:54.160 Once you've used it, you realize how much time it saves you by not having to make all these decisions, but to have
00:13:00.399 someone else make the decisions for you." So again talking about being
00:13:05.440 decisions being made for you, constraints being placed on you as a really good thing. Other communities have also figured this out. So that
00:13:12.320 really begs the question like what is a framework then really? Um, and I think based on my read of frameworks over the
00:13:19.519 years that a framework is really just a series of decisions made for you. And I believe that for that reason, frameworks
00:13:26.000 are sort of omas by definition. Which of course brings the question then
00:13:31.040 what's the opposite of a framework? Opposite of a framework is where you as the developer make all the decisions.
00:13:37.120 There's actually a Japanese term for the opposite of omacas. It's okonomi which
00:13:42.480 means how you like it. And this in in other words, this is choosing what to order instead of letting the chef do it
00:13:48.880 for you. So this is how most of us are probably used to eating at a restaurant. Find something you want on the menu, you
00:13:55.279 order it, the chef makes it for you what you ask for. And if you think about it, this okonomi style where you desri
00:14:02.079 decide what to order describes a lot of the tooling in other language communities like JavaScript.
00:14:08.800 Uh here's a Reddit post I found that sums up what it's like to work in JavaScript heavy stacks. And this
00:14:13.920 definitely mirrors my experience. Uh this poster says you don't want to include DOM types in your node library.
00:14:20.959 Well, now you just disabled the import of at types. Want to use ES6 imports?
00:14:26.160 Yeah, suddenly it doesn't work because somewhere down the node modules tree, some package uses common.js requires.
00:14:32.399 All the solutions are some old answers on Stack Overflow that don't apply anymore or don't work.
00:14:45.519 This guy says, "This is literally my whole career." Yeah, that that tracks.
00:14:51.839 So, I don't want to bag on JavaScript because I actually like JavaScript, but I do think that a lot of these smaller
00:14:57.440 tools that weren't work designed to work together are kind of uh a problem. Uh, and let's take a look at front-end
00:15:03.600 dependencies. This is sort of independent of any framework. Um, and and specifically, let's look at um
00:15:10.079 starter kits. So, as I said before, the JavaScript community tends to value lots of small packages, kind of the Unix
00:15:16.560 philosophy. Um, so let's look at the number of dependencies that these these starter kits bring with them. So, create
00:15:22.720 next app, okay, you know, not horrible. React router 285.
00:15:27.839 Uh, Redwood 478, that's starting to get pretty high. And then for create react
00:15:32.959 app weighs in at over,300 dependencies. These aren't all going to, you know, make it onto the front end,
00:15:38.480 but a good deal of them do. And that is just an enormous number of dependencies that could make it potentially come out
00:15:46.240 uh to you know and get loaded on your front end. Um it's sort of given rise to to this meme which I really like.
00:15:57.360 So let's look at some uh front-end decisions that you might have to make in 2025. And again this is sort of
00:16:02.880 framework agnostic here. Um you have to choose a JavaScript package manager. And
00:16:08.480 there are numerous uh package managers these days. Um of course npm yarn or pnpm but then even within those uh for
00:16:15.519 example for yarn there are different sort of versions of that as well. Uh 1.x
00:16:20.800 and then everything after that it's called berry I guess. Um why why it's
00:16:26.079 called berry I don't know. Um you might want to choose a bundler system and you have lots of choices there. Bun and ES
00:16:33.279 build or rollup or Webpack. Maybe you want to use import maps. Uh you might want something for for your like a CSS
00:16:41.040 uh either framework or build system, Tailwind, Bootstrap, Bulma, Post CSS,
00:16:46.079 Dart, SAS, the list goes on. Do you want to use TypeScript? DHH would say no, but
00:16:51.920 a lot of people want that. Um are you going to choose a CSS methodology? Is it
00:16:57.120 BEM or Smax or UK or Cube or Hex? Or maybe you want CSS modules instead. You've heard those are cool. Are you
00:17:03.839 going to choose a front-end framework like React or Vue, Angular, Spelt, Solid, Lid, Spence, St Spencil? Tons of
00:17:09.679 choices there as well. Or maybe you want to try HTMX or maybe you want to try inertia. These are all decisions that
00:17:15.679 you have to make. There are over 16,000 combinations of
00:17:20.799 just these few decisions that I wrote out in the previous slide. And that means that there are over 16,000 ways to
00:17:26.720 configure your front-end system. This is the opposite of omccas.
00:17:31.760 Um, let's look at the problems inherent in these front-end setups.
00:17:36.960 Uh, you end up making decisions all the time instead of actually working on your app. Build tools come in the or build
00:17:43.280 failures come in the form of useless error messages and stack traces deep inside transpiled dependencies.
00:17:49.679 Tools don't work well together because no developer accounts for all 16,000 permutations.
00:17:56.160 Um, debugging is hard because there's almost no indication of what actually went wrong. and upgrading is hampered by
00:18:02.559 release cycles that don't match up and exacerbated by the sheer number of dependencies.
00:18:08.480 Okay, so these problems I would generally associate with JavaScript first or JavaScript heavy front-end setups. Uh and for a long time, Rails
00:18:15.919 avoided most of these pitfalls. But let's take a look at the history of the Rails front end. Um as I sense some of
00:18:22.400 you have not seen uh the history before. So in Rails 3.1, before Rails 3.1 and
00:18:29.440 even including Rails 3.1, there really was not much of an asset story. It was static files. You'd write some JavaScript, some CSS, you'd link those
00:18:37.600 static assets uh in your head tag potentially, and that was how assets were delivered in Rails 3.2. We got
00:18:45.039 sprockets, the Rails asset pipeline. Um, a lot of people sort of love to hate on sprockets, but I think sprockets is
00:18:51.200 awesome, and it was way, way better than what we had before. Uh in 2014, Rails sort of added Webpack
00:18:57.919 as optional because these mod module bundlers were becoming a big thing uh in the JS world. Uh and then in 2019, there
00:19:05.120 was default the Webpack became the default and sprockets was kind of on its way out.
00:19:10.480 So um fast forwarding a few more years in 2021, um we start to get a little
00:19:18.559 crazy. So now as opposed to sort of one thing, now there's four things. CSS
00:19:23.760 bundling, JS bundling, import maps, prop shaft. It's a lot less omicass and a lot
00:19:29.679 more okonomi. And you might think, okay, well, these
00:19:34.720 things seem simple maybe, but it's actually hiding a lot of complexity. CSS bundling isn't just one thing. I can't
00:19:41.120 drop it in my app and suddenly write some CSS and it works. Instead, I have to make a choice between Tailwind,
00:19:47.840 Bootstrap, Bulma, both CSS or SAS.
00:19:53.679 Uh same thing is true of JS bundling. I have to make a choice here. Do I want to use you know ES build or bun or w up
00:20:00.640 Webpack? And I think what this is really showing is that the Rails front-end story could be a lot more cohesive.
00:20:09.440 Okay, so that was a a huge amount of content and now I'm going to introduce me. So I'm I'm not someone who likes to
00:20:15.360 share opinions widely, but that's what the next part of this talk is. So you might as well know who I am and maybe
00:20:20.400 why I should be taken seriously. So my name is Cameron Dutro. Um I used to work
00:20:25.440 for GitHub. I worked on the the view component framework. Um and I also worked on GitHub's primer team where we
00:20:31.280 worked specifically on primer view components which is a large collection of components for the primer design
00:20:37.679 system. Uh, I also am the author of Rux, which is a front-end framework or a front end uh templating language that
00:20:43.520 lets you write JSX style HTML snippets in your code uh for your templates. And
00:20:48.640 I'm also the author of several like pretty complex view components. So, I feel like I kind of understand a lot of the current front-end issues. Um, I've
00:20:56.400 also done some other crazy things. I tried to write a Ruby interpreter in TypeScript. If you want to talk about that, it's called Garnet.js. That was a
00:21:03.200 lot of fun. Um, and I do have a lot of front-end opinions sort of as a result of this of this work recently. Um, I
00:21:10.640 don't again don't like sharing opinions that much because I think they often don't come with qualifiers or nuance.
00:21:15.919 Um, but that said, I do have a lot of opinions and I want to share them with you today. Um, so yeah, these opinions
00:21:21.840 are based all the work that I've done over the past four years working on component frameworks, design systems.
00:21:27.039 Um, and I believe that most of these should be Rails defaults. So warning,
00:21:32.159 opinions are incoming. U I'm going to go through these rapid fire at first and then talk about them
00:21:38.159 in more detail later. So for a better time, use npm, use a
00:21:43.840 build system, use vit, use posts and bem block element modifier, use typescript,
00:21:52.080 and finally use web components stimulus and hotwire
00:21:57.440 for a better time. Also avoid these tools. Don't use import maps. Don't use
00:22:02.880 Webpack. Don't use a JavaScript framework. That I'm going to go into a lot of detail on that one later. I also
00:22:08.799 don't know if you really I I took this out, but I had it in the before. Don't use Tailwind. I think a lot of people like Tailwind, so I'm going to not say
00:22:15.520 that. I personally think that developing your own set of utility classes is more powerful, but I'm not going to put that
00:22:22.000 on the record. Okay. So, why npm? So, MPM is OG and it used to be kind of bad
00:22:30.640 and other uh packaging systems were sort of overtaking it. Um, but it's really
00:22:35.919 it's really good now. This is actually to the point where GitHub had switched from yarn to npm. Um, not just because
00:22:41.600 the company bought npm, but also because it was just much better than it used to be. So, so no really npm is good now.
00:22:48.320 Give it a shot. Um, yarn 1.x, X, which is I think what most uh people that
00:22:53.919 aren't using npm are using, is basically unmaintained at this point in favor of newer versions. Um, but I have
00:23:00.480 personally had really bad experiences with yarn 2 plus. Like I just cannot get it to work half the time, especially version 4 for some reason. So I would I
00:23:07.520 would I've always sort of stuck with yarn 1x when I have to use yarn. But again, I would say npm is the way to go these days. Uh, you talked about use a
00:23:15.679 build system. Um, no build is really cool, but we are not there yet. You need
00:23:22.559 a build system. I'm just going to come out there and say it. Um, maybe one day we can use import maps for real, but
00:23:28.240 that day is not today. But don't take my word for it. Dave Thomas agrees. Here's
00:23:33.280 a tweet he posted just a few uh weeks ago. He says, "I'm sorry, Rails, but
00:23:38.320 propshaft/importm isn't a happy experience. When it works, it's magic. but stray just a little from
00:23:45.039 the happy path and you get no insight into what's failing and where.
00:23:50.320 Okay, so as an antidote to that, use VIT. VIT is a uh combination of two
00:23:56.080 different tools. It uses ES build in development and it uses rollup in production. Uh ES build is extremely
00:24:02.320 fast, makes development really nice. All that it's really doing is concatenating behind the scenes. Um it also has
00:24:08.320 built-in TypeScript support. Um, rollup is slower, but it's battle tested and
00:24:13.360 you'll have to do it for for prod. So, there's no sort of waiting in development for it to to compile. Um, I
00:24:18.720 I like to say love yourself, use Vit.
00:24:23.919 But again, don't take my word for it. Uh, listen to Dave. He says, "Finally had a chance to get started with V
00:24:29.200 Rails. 20 minutes in and I've got all the external CSS and libraries loaded and running. No fuss, helpful errors,
00:24:35.679 and fast." That's a pretty good recommendation, I think. Okay, post CSS. This is a a post CSS, if
00:24:43.679 you're not familiar, is a CSS transpiler and and toolkit. I would say that post
00:24:49.440 CSS is pretty industry standard at this point. It's got a lot of momentum uh behind it, a lot of great tooling in it.
00:24:56.320 Um, it also has a really nice and rich plug-in ecosystem if you need to leverage that. Uh, and the Rails
00:25:02.720 generator for this, which comes with CSS bundling Rails, will add several of these imports for you or several of
00:25:08.320 these these uh, plugins for you, including the ability to import other files. Uh, nesting like you might get
00:25:14.559 with SAS or SCSS. Uh, auto prefixing for vendor prefixes and whatnot. And I would
00:25:20.480 go so far as to say because of this, you don't really need SAS or SCSS anymore. Um, post CSS can do all this stuff for
00:25:27.360 you. Next, use TypeScript. Don't listen to DHH. TypeScript is
00:25:34.480 wonderful and um I I personally have found much much usage in it and utility in it. Um I wish that Rails and and Ruby
00:25:41.600 had more typing. Um it just works out of the box with with V. Vita automatically has TypeScript support. Have to
00:25:47.679 configure anything. Um and if you don't want to use it in some particular cases, you can just use a JS extension instead
00:25:53.919 of a TS extension. No problem. Yeah, enjoy the power of types. They are amazing. There's a reason that a lot of
00:25:59.520 other languages are typed. Uh, use hot wire, stimulus, and web components. This is the Rails way. So,
00:26:05.279 that's one of the big reasons to use them. They're going to be supported for hopefully a long time. Um, they really require no extra dependencies aside from
00:26:11.840 what you get with Rails new. And they just provide a lot less bloat, I would say, than the frameworks. And one of the
00:26:18.080 big benefits, too, is they really they don't take over the whole page. You can specify individual sections of the page
00:26:23.440 that have these these JavaScript sprinkles. Uh and they also and this is a also a big pro or big plus they
00:26:29.840 leverage the web platform web components uh HTML over the wire. These things are all built into web standards. They are
00:26:36.400 not bolted on like React would do. Okay. Now the other big part of this uh
00:26:42.640 that I mentioned that I was going to go into more detail on is that you probably don't need a JavaScript framework. Now I know in the Rails community I think we
00:26:49.679 have heard this a lot but it still is so true in uh today's world. I think JavaScript heavy frontends have kind of
00:26:56.159 gotten out of control. Uh, and they're leading to poor experiences for consumers, especially those using
00:27:02.720 lower-end devices or accessing the internet over slow connections. Um, this is a quote from Alex Russell who has an
00:27:09.679 excellent blog infrequently noted. Um, he was a software engineer at Google. He worked on the web platform and the
00:27:15.120 Chrome browser for over a decade. He's now a PM on the Microsoft Edge team. And on his website, he claims that his
00:27:22.320 professional mission is to build a web that works for everyone. And Alex often publishes research around web
00:27:28.559 performance and is known for his biting criticism of poor web performances, often the result of overengineered
00:27:34.720 frontends. So, in a recent blog post, Alex writes, "To serve users at the 75th
00:27:40.080 percentile of devices and networks, we can now afford 150 kilobytes of HTML,
00:27:45.440 CSS, and fonts, and 300 to 350 kilobytes of JavaScript." That's not very much.
00:27:50.880 And this this is a few years old, but I think these numbers have not changed that much in the intervening years. And
00:27:57.120 yet, a number of the most popular websites and important websites out there have absolutely tremendous amounts
00:28:03.120 of JavaScript in their payloads. Um, a popular article published on tonsky.mme
00:28:08.240 blog a few years ago um sort of categorized some of these and described how crazy things are getting. Um, Zoom
00:28:16.080 comes in at 6 megabytes. Now, this is not the Zoom app. This is just the Zoom splash page on their website. Uh, and
00:28:23.440 like a login link or something. Why you need six megabytes to do that, I don't know. Patreon 11 megabytes, GitLab 13.
00:28:31.200 Again, that's just the login page. It's not even the whole thing, like the actual app. Instagram 16, LinkedIn 31,
00:28:37.039 and then for some reason, Jira coming in at 50 megabytes. Like, why? That's insane.
00:28:43.840 So, yeah, this has gotten absurd lately. Um, and just maybe to drive the point home even further, here's a tweet that I
00:28:50.159 found. Um, this guy says, um, if you load this page, this this page being a
00:28:55.520 Forbes article, it contacts 82 IP addresses, executing 256 separate HTTP
00:29:01.520 transactions to download 18 megabytes of data, writing 64 cookies to your device,
00:29:06.799 tell you no, Mission Impossible, The Final Reckoning, does not have a postredit scene.
00:29:16.080 So, JavaScript frameworks, I'm just going to come out and say this straight up, are hurting the web. In another part
00:29:21.520 of his or another one of his blog posts, Alex Russell writes, "Frameworkism isn't delivering." The answer isn't a
00:29:28.720 different tool. It's the courage to do engineering. Now, I don't know if that I
00:29:33.760 don't necessarily want to come up here and say that applies to Rails. I think it's mostly about JavaScript on the front end. Um, but I think this really
00:29:39.760 clearly illustrates that you really only need to reach for or you should only reach for a JavaScript framework when
00:29:45.279 you actually need one and most applications do not need one.
00:29:50.480 So what's the bottom line? Use npm vit post CSS TypeScript Rails defaults. If
00:29:57.440 you take nothing else away from this talk, I would say use Vit is the biggest one. That is such an easy. So yes, definitely use Vit. Um, avoid React and
00:30:04.720 other frameworks unless you actually need them. do engineering.
00:30:10.399 Okay. So, I would be remiss in this presentation if I didn't also have some code for you
00:30:18.240 to look at. Um, so I'm I'm I don't know if I'm announcing this or just making you aware that I'm I'm working on what I
00:30:24.000 call the velour gem. This is a Rails generator. The idea is that it bootstraps uh an omic ac
00:30:31.279 uh with a Rails generator. does this by
00:30:36.399 something. Oh, yeah. The mic.
00:30:50.399 Um, it creates a TS config file for TypeScript. Not strictly necessary, but helpful if you want to go and configure
00:30:55.600 it further. Hopefully, you you don't. Um it installs Overmind which I think is a better version of Foreman and uh along
00:31:03.440 with that it creates a better bin dev script with a debug option to make it easy to um spin up your background
00:31:09.440 processes and which includes V for example uh and your Rails app in the front end or the in the in the
00:31:14.480 foreground. Um and it installs everything using npm for JavaScript. So no no yarn. Um it also is available
00:31:22.480 here. You can look at it there. It's a work in progress currently. I haven't published it yet. I kind of want to put more omocas sort of things in it. Um,
00:31:29.679 but to do that I really would like your help. I would like to know what you think the omocas front end should look like in Rails. Um, and we can have a
00:31:36.480 conversation and produce this gem that then people can use to to bootstrap this for themselves.
00:31:42.399 Um, I also like to mention one last thing and that is that I'm also working on a Ruby based front-end framework for
00:31:48.720 when you really need true reactivity that lets you write your frontends in Ruby. Um, it's called Wisdom. You can
00:31:54.960 take a look. This is what the source code might look like if you were using Wisdom to write a front end. It has sort
00:32:00.399 of JSX style syntax and can render on both the front end and the back end. So, if you're interested in that, come talk
00:32:06.559 to me. I'd love to chat about it. And thank you for coming.
00:32:20.559 Looks like it looks like we have like a little over six minutes for for some
00:32:25.600 questions if there are any. Yes, right there. I just wanted to ask what your thoughts
00:32:33.120 are on npm versus PNPM. Yes. Okay. I unfortunately cannot speak
00:32:39.919 to that because I've never used PNPM. Um I would h I've heard lots of good things
00:32:45.679 about it. So so it's it's probably fine. By the way, I just I do want to say I'm not trying to say any tool is bad. I'm
00:32:52.080 just think I I just personally have found the combination of tools I talked about up here more compelling than other combinations. So anyway, yes.
00:33:00.000 Hey, hey, Cameron, nice talk. Um I would like to know your thoughts about ERB
00:33:05.600 view components and maybe flex. Yeah. Oh yeah. Oh my goodness, so many thoughts. Um, I think components in
00:33:13.840 general seem to be like a really powerful abstraction or abstract, that's
00:33:19.200 not the right word, a a code categorization system. Um, I think React like really nailed that. I think that
00:33:24.399 other language communities like ours um would are doing well to adopt that. Um,
00:33:30.320 flex is amazing. If you like that syntax, definitely use flex. Um, view component with erb templates also it's
00:33:37.039 sort of just a preference thing I guess. Um, flex is also faster. So if you want to use Flex for pure speed reasons, um
00:33:42.480 that could be a good reason to use it. Um they both have great communities. Um they both enable this componentized sort
00:33:48.799 of front end setup and so I'm definitely in favor of all that stuff. Yeah, I didn't talk about that in this talk just
00:33:54.000 because we're talking more about JavaScript and stuff, but um yes, big big fan of those things as well. You
00:34:00.000 were mentioning that import maps is still not there. What do you think is missing for only relying on import maps?
00:34:08.480 Yeah, it's a great question. So, I I think like the biggest reason in my mind
00:34:14.639 to avoid import maps is not because again import maps are not bad. They're a great idea, but I think the big problem
00:34:21.040 is if you want to do any form of of transpiling or bundling or any even even
00:34:26.159 the small like even if you just want to use TypeScript, you you have to use a bundler because you need the transpolation step, right? Um and and so
00:34:33.119 at some point when a browser sort of get native TypeScript support then import
00:34:40.159 maps could be a big a nice viable option. Um but I also think that like there's just there are so many other
00:34:45.599 dependencies that you might be pulling in especially if you're using something like React that you know either don't
00:34:50.960 support ES modules or are um you know incompatible in some other way. A
00:34:56.560 bundler kind of papers over a lot of those problems. And so import maps like you can get you know I would say 10% of
00:35:03.359 the my experience has been you get about 10% of the way through building your app and you need a bundler for some reason
00:35:08.480 and there's just no option to do any other like you're just literally dropping JS files from JS Deliver on the
00:35:15.839 page and like that only gets you so far I think. Um, since one of your main takeaways was to use Vit, can you expand
00:35:23.200 on that a little bit more um instead of just using ESB build for both production
00:35:28.560 and development? Yeah, so that's a great question. I So ES build is amazing. I find ESB build a
00:35:34.480 lot more difficult to configure than than Vit. I mean Vit especially with V Rails is just so drop in and turnkey
00:35:40.640 that there's for me that's the the benefit of it the the omocas part. It's like I just drop this thing in, I run
00:35:46.880 the install like rig task and I can write some JavaScript. Like that's really the biggest thing is like it's
00:35:53.040 just fast and easy. Um and then of course ES build by itself is is great.
00:35:58.240 Um I I think eventually like maybe we can just rely on ES build in the future like
00:36:03.680 when you know JavaScript kind of gets its act together and like everything works with ES modules. Um but but again
00:36:10.480 based on talking about the previous question like the bundling step is important because it papers over so many
00:36:16.000 problems with um you know different module systems and whatnot. And so you
00:36:21.040 know maybe at some point we can just use ES build and not even use um rollup because we don't actually need to bundle
00:36:26.079 and transpile things. We can just send it to the browser and that would be amazing. Hopefully we get that to that point at some time. I was wondering if
00:36:32.400 you have any favorite resources around um structuring CSS in a project or BEM primaries or that kind of stuff.
00:36:39.280 Yeah. Um I think with CSS what like I for CSS my
00:36:47.520 my my sort of intuitions I have I'm not much of a CSS programmer to be honest with you. Um most of that at GitHub for
00:36:54.000 example was done by other people. But the CSS that I did write and did see
00:36:59.359 this like scoping that to components can be really helpful because then you're not looking at a giant file and then of
00:37:05.119 course you have prefixing. That's one thing that BM does really well is it prefixes uh your CSS or it encourages
00:37:11.119 you to prefix your CSS with the name of the component. So instead of just saying um you know button color or something,
00:37:17.359 you're saying btn orb button dash you know color whatever. So you end up you
00:37:22.800 end up like having a a more I think um understandable CSS file per component.
00:37:28.320 Um and then maybe CSS modules along with that so that you're not namespace collisions. I think that though that
00:37:34.560 that's like often often CSS in my opinion gets really messy really quickly. So some it's really just about
00:37:41.680 like pick some system. It doesn't have to be BM. Pick some system stick to that so that everybody knows how classes are
00:37:47.440 written, how they're scoped. Um, maybe scope them to components using modules or something. Uh, just just do
00:37:52.560 something, right? Like don't just have like a a giant CSS file with everything in it, right?
00:38:01.599 Okay. I have 28 seconds left, but maybe we'll just call it there. Thank you everybody for coming.
Explore all talks recorded at RailsConf 2025
+77