Rails still encouraging us to use the asset pipeline for stylesheets and images?

Am I a fool for trying to use webpacker to compile stylesheets and images? I’ve only lost about a year fooling with it so far

We successfully use webpacker for stylesheet compiling, but I’m not sure about images. I think you’re on the right track with using webpacker but I must admit that our initial adoption was a bit challenging.

I still keep using sprockets for stylesheet. I am using it to perform performance techniques like inlined style. I failed to compile a single stylesheet file with webpacker. I have no interest to retry the migration until I see the benefits and a guide.

1 Like

There have been rumors or guesses that with Hotwire, Rails may go back to Sprockets.

1 Like

We’re still going strong on asset pipeline for css and images.

Although on new projects we have been using GitHub - rails/tailwindcss-rails and that works pretty well with webpacker for CSS.

1 Like

I use webpacker for styles, but I tried to upgrade to v6 beta and it did not go well. I’m not in the know, but it looked to me like webpacker is trying to focus more on JS specifically rather than all assets.

I’m in the minority, but I adopted webpacker two years ago initially for stylesheets only. I have some quite heavy templates, and reloading on development for every css change was just not feasible, so on Sprockets I was doing all css development in the browser dev tools and trying to remember to save. Switching to webpacker with HMR was a gamechanger. Doing actual code changes in my preferred editor with near instantaneous style reloading was necessary to even attempt the refactor project I was going to be working on. With Sprockets, my project would probably have been abandoned.

Now I’m using vitejs instead of webpacker for all assets, which is even faster on reloads as javascript changes instantly as well.

Wondering if you’d be willing to share your Vite setup for scss + js? It is the exact configuration I’m hoping to use on a new project.

Sure! I can post more details later, but here’s a general outline:

First step is using the wonderful and quite mature vite_rails gem. The docs are good too. For my project I struggled a bit with legacy browsers (there’s a legacy plugin for this, using Babel and core-js), but that was my code more than Vite, and I ended up doing a lot of testing with javascript disabled (to make it kinda work), and then putting the javascript bundle in a script type module tag so IE and Opera Mini don’t see the javascript at all. No javascript is better than broken javascript. (That also meant no legacy gem, which simplifies things. YMMV.)

Sass is a lot easier than in webpacker. You only need to yarn add sass, and that’s it. Then you can use latest dart sass without worrying about when/if the webpack loader will upgrade. My refactor project was on a Rails 5.1 app, so I couldn’t upgrade webpacker to a version that supports dart sass, but with vite I can.

One difference is that the webpacker gem adds a lot of config because webpack is so complex. The Vite integration adds very little since Vite is so easy to configure on its own. postcss doesn’t run until you install it, for instance, but it’s a first class citizen, so it will pick up your postcss config without any changes to the vite config at all (same as with sass). You of course have to install every dependency, I’m thinking mainly of autoprefixer and postcss-preset-env (which are bundled with Webpacker).

But the big difference is development. Esbuild (which builds and reloads the development files) is a game changer when it comes to speed. The fact that the vite_rails developer also has a stimulus helper and a stimulus HMR loader is the icing on the cake for me, it meant literally no waiting times in development when doing css and javascript changes.

Looking at recent commits and new gems, it feels like Rails is moving to a place where bundling and transpiling are considered unecessary

For JS, every evergreen browser supports ES6, so transpiling is unecessary, and every CDN/browser supports http2, so bundling is unecessary (this is the working theory, not an established fact). The result of this is import maps. But if you still need bundling (I do), jsbundling-rails is the way to go, as it’s a minimalistic and more flexible version of webpacker that supoorts multiple js bundlers.

For CSS, it’s a bit more complicated. Rails is betting that utility first CSS like Tailwind is the future. I agree, and have in house utility first css library based on the design system defined by our UX team. But I still rely on Sass and bundling for that. CSS is a render blocking resource on browsers, so even with HTTP2, you should still only have one file. Therefore in my opinion cssbundling-rails is your choice.

Finally sprockets, which is what most people associate with the asset pipeline, is still going to be supported, but it’s spiritual sucessor is coming, and it’s going to offload many of sprockets reponsibilities to jsbundling and css bundling. https://github.com/rails/propshaft.

So, to resume: rails is still betting on the asset pipeline, but it’s going to modernize it. If tailwind and importmaps are not enought for you, skip sprockets and webpacker and go with cssbundling and jsbundling, so that when propshaft reaches version 1, your migration will be easier.


This is an improvement on Sprockets (which badly needed an improvement), but without HMR I’ll stick with Vite. Reload after rebuild and watching on save - no thanks. Also, I don’t know why these tools doesn’t want to do minification. Minification + source maps is a good practice for a reason.

I understand where all this is coming from, but if you have an interest in the frontend that goes beyond “I want node to go away”, then I honestly don’t think this is a good idea. I don’t think bundlers are the problem, I think the particular one called webpack is. I think making bundlers good (i.e. not webpack) is a better option. Unbundled development with HMR coupled with a good bundler like Rollup for the deployment is too good to miss, in my opinion. For me it’s all about development speed. Reloads slow you down. (Then again, if you’ve gone all in on Tailwind you might not notice since you mostly write html and not css.)

The scenario you are describing is also the scenario that Propshaft is being built to work in. Propshaft said: “You know what? The node ecosystem is pretty good at this bundling and handling css and js, so there’s no need for me to handle this like sprockets. I’ll just be responsible for moving stuff around and serving the files and get out of the way.”

It’s companion gems (jsbundling and cssbundling) support rollup, esbuild and dart-sass.

Since major features of Rails are usually extracted from production apps (basecamp/hey, shopify, github, etc) it’s natural that they tailored to specific use cases at first, before the community joins the fun.

Active Storage at first wasn’t compatible with cdns, couldn’t create public links, and only had support for imagemagick, but we (regular contributors) solved most of those problems.

So think of Propshaft and companions as the gems where all the legacy that held back Sprockets no longer exist and we can all push them further them before, instead of something that has gone in the wrong direction and that anyone interested in frontend can’t use.

After all, we are programmers. We wage war on what’s the best editor. It’s a give. We won’t agree on everything.

Yeah, sorry for sounding a bit harsh there. I’m just religious when it comes to HMR and development (like I said, I have lots of heavy templates, and even with caching in development I doubt I even would have started my refactor project without HMR). Also, I don’t enjoy working with Tailwind at all, partly because I think it’s a poor fit for the semantic web and partly because ironically it slows down development because you need to rerender the template instead of instantly changing the CSS on screen. So this isn’t my favourite direction for Rails frontend to take. But never mind me, I’m probably weird! And I already have vite_rails. :blush: