Frontend in Rails will be very different from Rails 6.
JavaScript in Rails 7 will be different: the Webpacker gem has been retired, and there are 2 new gems to manage frontend files.
In this article:
Webpacker was the gem that Rails used to integrate Webpack, and Webpacker 5 will be the last version. The Webpacker 6 release candidate is now going to be community-maintained under a new name. (source)
There are now 3 options that I know about:
importmap-rails — This gem is the new Rails 7 default. The importmap-rails gem allows using npm packages in the Rails asset pipeline.
jsbundling-rails — An alternative that unifies support for any Node.js-based bundler (Webpack, Rollup, esbuild) under one gem. However, it only supports a subset of features that Webpacker does.
shakapacker — A community-supported continuation of Webpacker maintained by Shakacode, now called Shakapacker.
The importmap-rails
gem will come pre-loaded in Rails 7, and seems to be the answer to the question “how do I use npm packages in Rails?”.
Import-map is a lightweight tool to transform imports from npm module names (eg, “react”
) into URL’s, useful for loading scripts from an external CDN.
Yes, using import
in the browser is natively supported by all modern browsers—no bundlers needed! Importing URL’s inside a script tag should work. (docs)
There is no “build” or “compile” step in importmap-rails. There’s no Babel, PostCSS, or anything that transforms JavaScript code.
No npm/yarn required. It can be used with npm, but the recommended experience appears to be to use the jspm.org CDN. (article)
What about JavaScript modules (“esm”)? While Babel has often been used to convert ESM modules into common JavaScript code, Rails with importmap doesn’t do this. Instead, it relies on browsers’s built-in ability. (docs)
Limited React support. Because there is no compilation step, there is no support for build-time JSX compilation (it would have to be done on runtime using something like htm).
Limited legacy browser support. import-map relies on <script type="module">
which is not supported on IE11. (caniuse)
It doesn’t combine many JavaScript files into one, unlike bundlers like Webpack. Rather than serving all files under one application.js
, import-map will load all files individually(!).
Most applications would often serve a bundle of JavaScript like that above. However, import-map’s approach would be to not bundle the files, and serve them individually instead:
No tree-shaking. Since npm packages are loaded as-is (and often from a CDN), the benefits of removing unused code (“tree-shaking”) isn’t available when using importmap-rails.
HTTP2/SPDY is needed. Well, not required, but HTTP2 multiplexing will be needed to make loading hundreds of JS files a practical solution. (codavel.com: HTTP2 Multiplexing explained)
The jsbundling-rails gem appears born out of the desire to use Webpack alternatives in Rails.
While Webpacker offered very tight integration with Webpack (even its configs are in Ruby and Yaml), jsbundling-rails is a more “lightweight” integration. The main source code is less than 20 lines: all it does is invoke “yarn install && yarn build” before asset precompilation.
Apart from Webpack, there are other bundlers supported. esbuild is a very fast alternative written in Go, and Rollup is a popular alternative often used with libraries.
Seems straightforward. The goal is to set up Webpack as you would in a Node.js project (eg, work without Webpacker) and that’s it. The jsbundling-rails migration guide has more details.
No code splitting support. Webpack’s ability to lazy-load certain parts of the bundle is not supported. (webpack.js.org: Code splitting)
No hot reloading. Be ready to press F5 a lot.
The work on Webpacker has been continued by ShakaCode and was named for their company. Shakapacker is based off of the unreleased Webpacker 6. (The last Webpacker version is 5.)
import-map | jsbundling | shakapacker | |
---|---|---|---|
npm modules | CDN only | ||
Code splitting | - | - | |
Hot module reloading | - | - | |
React JSX support | - | ||
Delivery to the end user | Multiple files | Bundled | Bundled |
Tree-shaking optimisation | - |
I am a web developer helping make the world a better place through JavaScript, Ruby, and UI design. I write articles like these often. If you'd like to stay in touch, subscribe to my list.