How to assemble Rails frontend using Webpacker?

Frontend developer's tips for a painless migration from Sprockets
05 July   4236

What's wrong with Sprockets

Sprockets, aka RoR Asset Pipeline, has become obsolete long time ago. Frontend is evolving with leaps and bounds, and Sprockets is not keeping pace. As a result we have plenty of problems. Some of them:

  • Limited support for new frontend tools. For example, you will face issues using PostCSS plugin or use a much faster SASS libsass compiler instead of written in Ruby.
  • No support for ES2015 transpiling
  • No support for javascript modules
  • No support for sourcemaps, which has existed for many years

Also, Sprockets configuration has low flexibility. Guess what Sprockets will do if you disable minification and pass through it some minified javascript. Sprockets will deminify the code and insert comments everywhere trying to emulate sourcemaps. I've never found how to disable this behaviour.

Ruby on Rails

Ruby on Rails (RoR) - a framework written in Ruby programming language.

Sprockets is being slowly developed. Version 4 was supposed to solve some problems and it was promised to be released with the Rails 5, but this has not happened so far.

At the same time, Sprockets is a rails-specific tool, but the frontend evolves by itself and the community prefers to use and create universal tools that don't have any specific limits. So, with help of node.js there were created task runners (for example, pretty popular gulp) and module bundlers (webpack, which is able to resolve dependencies between javascript modules, concatinate everything in the right order and remove the redundant code).

It is worth mentioning package managers in the context of frontend. If you use Sprockets, most likely you use gems to import any frontend-associated libraries. Because it's a common way. The problem is that authors of such libraries don't care about creating and maintaining gems, they use npm and bower repositories. So, you have to use a third-party gem and hope that it will be somehow maintained or you can use crutches like

All this has bothered me for a long time and not just me. As a result we had various attempts to tape gulp, webpack and Rails together. It worked but it also took time and nerves. And now it can be left behind.

What's great about Webpacker 

Webpacker is a Rails gem that provides smooth and standard integration with webpack module bundler and yarn package manager (it's like modernized npm). Optional integration with popular frameworks / libraries such as react, angular, vue is also available. The current version of Webpacker is 2.0 for the moment when I write this article.

Requirements are:

  • Rails 4.2+
  • Ruby 2.2+
  • node.js 6.4.0+
  • yarn

If you have Rails 5.1+ you can use the --webpack option, because Webpacker is delivered "out of the box" with this version. For example:

rails new webpacker-example-app --webpack
// or this to setup react or angular or vue 
rails new webpacker-example-app --webpack=react
rails new webpacker-example-app --webpack=angular
rails new webpacker-example-app --webpack=vue

In case of Rails 4.2+, you can install Webpacker by adding it to your Gemfile and running the following command after installing the gem: 

rails webpacker:install
rails webpacker:install:[react, angular or vue] (optional)

This command will check the compliance with the requirements and take care of creating: 

  • Scripts for running webpack and webpack-dev-server in the bin directory
  • The app/javascript directory
  • The config/webpack directory and webpacker.yml
  • The packages.json (analogue of Gemfile for npm) with necessary stuffing. Then it will run the packages installation with yarn, which will create the node_modules directory and the yarn.lock file

Default packages list includes Babel, so you will be able to use the newest Javascript syntax.

Setting everything up

Webpacker suggests to follow certain conventions, but you can change everything quite easily, look into the config/webpack directory and config/webpaker.yml.

Webpack Configuration

The config/webpack directory has corresponding configuration file for each Rails environment. Also there is shared.js file, that is common for all environments, and configuration.js file, which is responsible for processing settings from config/webpacker.yml.

The production.js configuration by default commands webpack to assemble all modules into single bundles, to minify the code, to add fingerprints to file names, generate sourcemaps and even compressed gzip versions. So that is even more than Sprockets able to do, but everything can be configured as you like. You can add or remove steps from an assembly process and you can modify them. For example, you don't need gzip versions. No problem, just remove them from the config.

The config/webpack/loaders directory, contains loaders which are responsible for processing and transforming files according to certain rules. They are similar to tasks from other build tools. The babel.js loader is responsible for .js and .jsx files and instructs the babel transpiler to convert code written with ES2015 syntax to ES5 code. The coffee.js loader is responsible for .coffee files and also turns code into ES5. Again, everything can be configured, added or removed.

Styles Processing

Webpacker was originally intended to solve problems with javascript, not for replacing Sprockets. It was assumed that Sprockets will continue handle styles and other assets. However, the styles code, just like javascript, can be handled by your favourite preprocessor's loader. Webpacker by default generates the config/webpack/loaders/sass.js file, which contains configuration for processing styles written in sass/scss. It is done to make working with styles easier for applications built with component approach, React.js or other similar tools that allows you to include styles directly in components. But you don't have to follow this approach, so I recommend to use webpack to assemble styles.

The Webpacker installation also integrates PostCSS into the assembly. It adds a lot of possibilites and flexibility to styles management. The PostCSS configuration is in the .postcssrc.yml file in a project's root. There are list of plugins:

  • precss, not so useful when we already have scss
  • autoprefixer, a great tool that allows you to forget about writing browser vendor prefixes

Unfortunatelly, there is no "out of the box" feature to conveniently include assets in css code. I mean functions like asset-url and asset-data-uri from Asset Pipeline. But there is a solution - the postcss-assets plugin. In order to install it execute yarn add postcss-assets -D. This will add the package to the packages.json list and install it. Then we need to add changes to .postcssrc.yml, my config looks like this:

  postcss-smart-import: {}
  precss: {}
  autoprefixer: {}
  postcss-assets: {
    loadPaths: ['images', '../app/assets_src/images/'],
    basePath: 'public',
    cachebuster: true,

Your loadPaths most likely will be different. I recommend to look at readme file and to play with configuration.

As a result, you will be able to use resolve and inline functions in your css code.

Directory structure

Webpacker creates the new app/javascript directory and it is suggested to store there all the javascript code and entry points for webpack (so called packs). The convention is that entry points are placed in the app/javascript/packs directory, and javascript modules are placed in the app/javascript.

For various reasons styles are expected to be placed in the same app/javascript directory. But the good thing is that it's easy to configure it in config/webpack/shared.js. Look for resolve.modules which is an array of paths used by webpack to search for files. The first item is resolve(settings.source_path). source_path here is taken from config/webpacker.yml. So, for my own project I've set the source_path: app/assets_src, and modified resolve.modules like this:

modules: [


Webpacker adds two scripts for running webpack:

  • bin/webpack for a one-time assembly
  • bin/webpack-dev-server for 

I recommend to check the content of this files.

Also, in order to build your assets in production mode, for example for testing purposes, you can pass the --config param with a full path to the corresponding config file.

Note that if you or your colleague has added some modules to packages.json it will require installation. Otherwise webpack will throw an error saying that a module is missing. Just run yarn command in the project's directory, just like bundle install but for npm packages.


Webpacker adds a new task webpacker:compile, which runs every time when the assets:precompile is run. If you have completely abandoned Sprockets, then you can manually run the bundle exec rails webpacker:compile command during deploy.

Including bundles into views

Very similar to the Asset Pipeline. Use new javascript_pack_tag and stylesheet_pack_tag helpers. They will add necessary HTML tags with links to assembled packs.

Setting up Continuous Integration

Continuous integration

The practice of merging all developer working copies to a shared mainline several times a day



Cloud Continuous Integration service, unlimited parallelis

If you are using a CI system, then of course you will need to configure it: add node.js and yarn.

At Evrone, we successfully use So, the configuration for Vexor with Ubuntu server will look like this.

The vexor.yml file in the project's root will contain

  - 2.3
  - 6.11.0
  - ./
  - bundle install
  - yarn
  - bin/webpack

The script looks like this:

#!/usr/bin/env bash
set -ex
curl -sS | sudo apt-key add -
echo "deb stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install yarn

Don't forget to make the file executable: chmod +x


I've moved my current project to Webpacker but I advise you to think carefully before doing the same. Think about if it will worth for you some time that the transition will require. Nevertheless, you can use it for all new Rails projects.

How to redirect to 404 page in Rails?

Small tutorial that will help you to redirect user to a "fake" 404 page, using Rails
31 October   308

Rails has this functionality built in already. If you want to show a 404 page, create a render_404 method (or not_found ) in ApplicationController like this:

def not_found
  raise'Not Found')

Rails also handles AbstractController::ActionNotFound, and ActiveRecord::RecordNotFound the same way.

This does two things better:

It uses Rails' built in rescue_from handler to render the 404 page, and 2) it interrupts the execution of your code, letting you do nice things like:

  user = User.find_by_email(params[:email]) or not_found

without having to write ugly conditional statements.

As a bonus, it's also super easy to handle in tests.