Article  |  Development

Rails and the Asset Pipeline in 2023: Part 1

Reading time: ~ 5 minutes

Rails and the Asset Pipeline in 2023: Part 1

There have been many changes in how Rails handles CSS and JavaScript over the years. Initially, all developers had to do was place static JS and CSS files in the public directory and let them be served by the application’s webserver. Over time web applications grew more complex, and our needs for asset management became more complex.

For the JavaScript parts of an application, the need for including 3rd party modules and multiple polyfills to create applications with rich interactivity and responsiveness has meant that what were once static files served directly to the end user now require numerous processing steps before they can be served.

As of 2023, a proliferation of tools and libraries can be linked together to do this. In the Ruby on Rails context, new libraries are being released, and old ones are being deprecated. This article will review each of the most common asset-pipeline-related gems and libraries in 2023 and briefly describe each one, its history, and where it fits into the larger picture of asset compilation.

In the Part II article that will be shared in the coming weeks, we will review use cases and build a decision tree for deciding which libraries to use when and how to approach upgrading existing applications away from deprecated libraries.

Now let’s take a closer look at each gem so you can understand its purpose and functionality. I’d also recommend that you read the gem's documentation, README file, and any accompanying guides or tutorials to understand what it does and how it can benefit your Rails application.

Sprockets

Sprockets was introduced in Rails 3.1 in 2011 to handle processing JavaScript and CSS files. Its goal was to “make[s] CSS and JavaScript first-class code citizens” of a Rails application by allowing the use of then-modern tools such as CoffeeScript and SCSS. Sprockets, written in Ruby, fulfills the same functions as the JavaScript tool Webpack - processing and packaging assets (JavaScript, CSS, and images) for production use. In Rails 5.1, Sprockets was deprecated in favor of the Webpacker gem, a Ruby interface to Webpack. As of 2023, nearly all preprocessing libraries for Sprockets (SASS/dartsass, sprockets-esbuild for JSX, Babel support) are all deprecated or no longer under active development.

  • It is compatible with Rails 3.1+.
  • Homepage: https://github.com/rails/sprockets
  • Roles: Transpilation/bundling/minification, relocation, digest-stamping, providing Rails view helpers for inclusion of stamped assets.

ruby gems image

Webpack

Webpack is a JavaScript build tool written in JavaScript that runs on Node.js. Webpack development began in 2012, and version 1.0.0 was released in 2013. Webpack’s primary purpose is to bundle JavaScript files for usage in the browser. Before the advent of HTTP/2, bundling all frontend requirements into as few files as possible was required for performant web applications. Webpack also supports various modules for preprocessing. Typical usage in a rails application context is to preprocess and bundle assets (JavaScript, CSS, and images) as part of a deploy pipeline. Webpack and its most commonly-used modules for preprocessing are still under active development as of 2023.

  • It is compatible with Rails 5.1+ with the use of Webpacker gem (see below).
  • Homepage: https://webpack.js.org
  • Roles: Transpilation/bundling/minification, relocation, digest-stamping

Webpacker

Webpacker is a ruby gem wrapper around the webpack javascript library. Webpacker was introduced in Rails version 5.1 to migrate away from using sprockets_ _to compile assets. Sprockets was falling behind Webpack in features and package compatibility. Webpack is well-supported by the JavaScript community and compatible with npm repository packages.

  • It is compatible with Rails >= 5.1 (may work with older versions with extra configuration or shims).
  • Homepage: https://github.com/rails/webpacker
  • Roles: Ruby interface with webpack, providing Rails view helpers for inclusion of stamped assets, provides rake task assets:precompile

importmap-rails

Importmaps allow the loading of javascript dependencies without bundling them into one file. With the advent of HTTP/2, this no longer carries a performance penalty. This can make the development process easier, as debugging javascript bundle files requires creative ways of picking them apart again. Keeping files separate also allows for better caching, as individual dependencies can have their caches expired individually. Importmap-rails is a Ruby library that uses Ruby code to configure and generate import maps. Instead of bundling all dependencies into one file, an importmap contains a list of dependencies and locations to access them. This can be on the application’s server or a 3rd party CDN server. Importmap-rails is still in beta development, although it is functional and has been reported in use in production environments.

Propshaft

Propshaft is a replacement for sprockets. Propshaft does not perform bundling or preprocessing, instead preferring to delegate those tasks to a dedicated tool such as webpack. Propshaft provides features more specifically designed for use in a Ruby on Rails context. This more minimal approach allows steps and tools in the asset pipeline to be swapped in and out as they are developed and deprecated. Propshaft can be used with a bundler/compiler such as webpack or esbuild, importmaps-rails, or standalone if an application’s javascript needs are minimal. Propshaft will copy all assets (which may or may not have already been preprocessed by a library such as webpack) into a single directory so that they may be accessed and served by the webserver in a Rails context. It also stamps assets’ filenames with digests of their contents to allow for efficient caching and provides Rails view helpers to include the stamped assets on pages generated by the Rails application.

  • It is compatible with Rails 7.0.0+.
  • Homepage: https://github.com/rails/propshaft
  • Roles: digest-stamping, relocation, providing Rails view helpers for inclusion of top-level assets, providing rake task assets:precompile

jsbundling-rails

Jsbundling-rails provides an interface between Rails and the JavaScript build tool of your choice (esbuild, rollup.js, or webpack). It provides or modifies rake tasks so that asset build processes can be triggered in a way familiar to Rails developers and easily integrated into application test suites and deploy pipelines. Requires sprockets or propshaft to provide Rails view helpers and asset digest stamping.

  • It is compatible with Rails 6.0.0+.
  • Homepage: https://github.com/rails/jsbundling-rails
  • Roles: adds javascript processing rake tasks and modifies assets:precompile rake task to include javascript processing (requires the base task to be provided by another library)

jsbundling image

cssbundling

Cssbundling-rails provides an interface between Rails and the CSS processing method of your choice (Tailwind CSS, Bootstrap, Bulma, PostCSS, or Dart Sass). It provides or modifies rake tasks so that CSS build processes can be triggered in a way that’s familiar to Rails developers and easily integrated into application test suites and deploy pipelines. Requires sprockets or propshaft to provide Rails view helpers and asset digest stamping.

  • It is compatible with Rails 6.0.0+.
  • Homepage: https://github.com/rails/cssbundling-rails
  • Roles: adds CSS processing rake tasks and modifies assets:precompile rake task to include CSS processing (requires the base task to be provided by another library)

cssbunding image

The Evolution Continues

The topology of the asset pipeline in Rails has shifted over the years. What was once a monolith, with all functionality provided by a single library (sprockets), is now much more modular, configurable, and interoperable with modern JavaScript libraries and frameworks. This increased configurability and extensibility continue to keep Ruby on Rails an attractive choice for a wide variety of web application use cases. At the same time, the proliferation of configuration options makes it imperative that application architects understand the various libraries and tools available to them, closely examine their application’s requirements and accurately identify which ones meet the needs of their application and its environment.

In Part II of this article (coming soon!), we’ll build a decision tree of which libraries and configurations are appropriate for which requirements. We will also discuss the topic of upgrade paths for existing applications based on this author’s experience. I hope you’ll join us!

Have any additional questions about the Rails Asset Pipeline, or just want to talk shop? We're always happy to chat!

Have a project that needs help?