I saw this comment online somewhere: "What I really don't understand is what exactly webpacking does." A lot of Rails developers feel that way. But it's easy enough to clear up.

The Short Answer

  • Do not ever use Bundler to install JavaScript or CSS of any kind. It was a great idea back in the day, it is a terrible idea now. If a tutorial tells you to install Bootstrap with Bundler, for example, that's just out of date and wrong.
  • If you do not plan on doing anything fancy at all with your JS or CSS, you can still use the asset pipeline (also known as Sprockets), but if you want to do anything custom with it, you'll run into trouble.
  • Webpacker is the foundation you should use for most Rails front-end setups. It's also got very handy installers for common front-end libraries and frameworks. It's a nice, solid basic starting point.
  • But if you plan to do anything interesting or unusual with your JS and/or CSS, you need to understand Webpack, and especially know how to make some basic edits to Webpack config files.

In practice, most Rails apps today use both the asset pipeline and Webpacker. If you put all your javascript in app/javascript/ or app/javascript/src in a Rails 6 app, Webpacker will automatically package it up, and if you put all your CSS in app/assets/stylesheets, the asset pipeline will automatically pick that up too. In my personal apps, I only use Webpack and Webpacker — because Webpack can handle CSS as well as JS — but that's a topic for another blog post.

I may write that post at some point in future, but for now, there's more detail available on this question, if you want it.

The Long Answer

In a Rails app, you write your back-end code in Ruby. There are a lot more options for your front-end code, and it can get a bit confusing.

But you only need to understand two things before you can understand the murky relationship between Webpack, Webpacker, Bundler, and the Rails asset pipeline (also known by its original name of Sprockets). Here they are:

  • Web browsers understand JavaScript, HTML, and CSS, but web developers will often use other languages which compile down to JavaScript, HTML, and CSS.
  • Rails solved this problem almost a decade before anyone else — but that means that the default Rails solutions are legacy code.

Web Browser Languages vs. Web Developer Languages

The web browser understands three languages:

  • HTML, which sets up a document's structure and content.
  • CSS, which adds styling such as colors, fonts, and layout.
  • JavaScript, which allows your web page to respond to user input by changing the HTML or the CSS in some way.

All three of these languages kind of suck, a little, and a decade ago, they sucked a lot. They sucked so bad that words fail me. Let's just leave it at this: they SUCKED.

So web developers began creating languages that would compile down to JS, HTML, and/or CSS. You write it in a good language; you run the compiler; the compiler outputs JS, HTML, and/or CSS; and you feed that to the web browser.

(In many real-life examples, though, it's only JS and CSS; Rails already has a way to send the HTML.)

Rails Solved These Problems Early

Rails innovated in this area very early on. We had Ruby compiling down to JavaScript as early as 2005. But when you have a system which compiles Ruby to JavaScript — or which turns any web developer language into any web browser language — you then have two new problems to solve:

  • How will we get this JS and CSS across the network to the web browser?
  • How will we manage dependencies?

In other words, once you've compiled your JS and/or CSS from whatever other language is easier to write, you now have to get the output down the wire. Life is easier for a developer when you split all the different parts of your logic into different files. But when you send it across the network, your browser performance will be better if it's just one file.

Meanwhile, dependency management is something every large system has to deal with, because, again, every large piece of software is going to be made of a lot of smaller pieces. You have to get them from somewhere, install them, and keep them up to date.

And that brings us to the difference between Webpack, Webpacker, Bundler, and the asset pipeline.

  • Sprockets, aka the asset pipeline, was an early Rails system for taking all the individual, small JS and CSS files that you wrote and compiling them into one big JS file, and one big CSS file, to transmit to your web browser. Rails is keeping it alive for the sake of backwards compatibility.
  • Bundler, which every Rails app uses for Ruby gems, was for a long time also a very useful way to install JavaScript libraries, mainly because the JavaScript world did not have any other system at all for the purpose. Bundler was designed to install Ruby libraries, and using it to install JS and CSS libraries used to be a clever hack. It's now just a bad idea.
  • Webpack is a much more powerful way of compiling JavaScript which the JavaScript community developed much more recently. You can also use it to compile CSS, although that is a sophisticated use case.
  • Webpacker is a Ruby wrapper around Webpack which streamlines a few very common (JavaScript-only) use cases.

Webpacker & The Asset Pipeline To Start; Webpack For Advanced Users

So there you have it. If you're just starting out, use Webpacker for JavaScript and the asset pipeline for CSS. If you're a more senior dev, use Webpack for both.