How to assemble Rails frontend using Webpacker?

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

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.

A. Patterson: "I Wanna Write Ruby Extensions With Rust"

Interview with Aaron Patterson, Ruby Core Team and Rails Core Team member, senior software engineer at GitHub
24 September 2018   1332

Aaron Patterson is Ruby Core team and Rails Core team member, senior software engineer at GitHub, Ruby Hero 2010, speaker at Rails Club 2014 and Ruby Russian 2018 and cat lover.

Aaron Patterson and his cat
Aaron Patterson and his cat

Let’s start with the standard question. What’s your personal ruby story? How did you get on this train? What did you achieve? How do you make this world better?

I’ve first discovered the language in 2006. I was a Java programmer at that time. Let’s go back a little bit further. I used to be a Perl programmer, and then I became a java programmer, but I didn’t wanna be a java programmer. Ha ha!


When I was a perl programmer we actually had our own web framework. We did a lot of the stuff that Rails did: уou can just change stuff, reload the page and test it. And everything just worked. When we switched to doing Java development, it was like - you have to re-compile everything, then it will take 10 minutes before you can test any changes you’ve made. I like dynamic languages like Perl better than Java. So, I was waiting for Perl 6 to come, and while I was waiting for Perl 6, I discovered Ruby. I was like: “Oh, wow! This is what I wanna do!” So, I just started doing Ruby in my free time, like, for side projects. You know, just fun programming stuff. That’s when I very first discovered it. I finally got a job doing Ruby programming in 2008.

That was already Rails?

Yeah, some friend of mine decided to start a startup. “We gonna use Rails. Do you wanna come with us and join our company?”. I was like: “Yeah, absolutely, I’d love to use Rails for my job!” That’s first time I’ve started it.

To be honest, I did not like my job when I was at that company. Ha-ha! So, what I did was - wherever I could, I wrote open source code at work. It was like: “OK, this project will take 2 days.” I got the project done in few hours and used the rest of time for open source code.

That’s what in Russia we call: “Don’t beat a lying person!” Haha! I’m just sitting here quietly, doing things. Please, leave me alone!

Yep! Haha! So, that’s where I’ve started doing a lot of open source work. At that job I’ve first started writing Nokogiri and working on my Ruby open source stuff. That’s where I’ve started with open source world. I’ve just kind of participating until one day I just got on the Ruby Core Team and Rails Core Team.

How did you eventually find yourself at the Rails Core Team?

We just kept finding bugs and developing Rails applications. We were running into bugs;  I’ve fixed the bugs and submit patches. I just kept submitting patches. Eventually, they got tired of me sending pull requests. Haha!

Just try to manage all this stuff yourself, right?

Yes, exactly! So, it was basically like a brute force attack! Haha!

Sounds reasonable! So, what’s your overall contribution to Rails?  

I worked a lot on basically all parts of the framework. I mostly work on Active Record. I personally like to do bug fixes and performance improvements. The reason I like doing that stuff is because it’s just doing everybody’s applications better. Everybody’s happy if the app gets better and you don’t have to do anything. That’s why I like working on that stuff.

You make some kind of “small” contributions which makes thing work. But didn’t you actually architecture “big” things?

Usually, whenever I do architectural stuff at Rails it will be stuff at internals. Like, how we do, for instance, URLs architecture, associations architecture, stuff inside the router, things like that. None of those things are necessarily exposed. They may be kind of expose to the user but they not like “Hey! This is the Thing! Go do this!”  I try to stick to that kind of stuff. I think it actually works well because I think David likes to do flashy awesome new features. I personally think: “OK, we’ll do those cool features. They are actually awesome!” Ha ha!

Yes, somebody has to do all the job! Your presentation at the conference will also touch some deep engineering parts of Ruby and Rails. What’s your presentation will actually be about?

I’m gonna talk about Ruby internals actually. I am still thinking what I’m gonna talk about.

GC, performance, everything, life, universe, 42?

I’m gonna talk about garbage collector, Ruby’s compilation process and bytecode. Basically, about the bytecode in a virtual machine and how those relate to the garbage collector. About some performance improvements I’ve made to the GC. I don’t think I’ll be talking much about Rails stuff at all. Haha!

Good note! Our conference was formerly known as “Rails Club”. Basically, after Matz said he’ll never be visiting the conference named after Rails, our organizers changed their minds and renamed the whole thing. So now we are “Ruby Russia”!

So, I will speak about Ruby internals.

In your opinion, what should Rails programmers do in their code to achieve better performance?

There are few different strategies. The first one, something like basically don’t do anything special. Just write your application. Get it done, get it out there, get customers, feedback, etc. As soon as you start doing that analyze the bottleneck. Don’t ever deal with any bottlenecks until you actually get customers using it. If you spend time working on bottlenecks, that are not actually a bottleneck - that’s basically a waste. You could’ve been writing new features. But I think a lot of people say what I’ve just said, so, let’s talk about actual performance stuff. First thing you do is just look at the database queries that the page is doing. It’s first line of attack - try to reduce the amount of time it takes for particular queries. Automating the queries, reducing the queries. You’ll be surprised how many times we forgot to add an index. Haha! So, add the index at the right place.

I’m doing the job interviews at our company and I understand how people forget about indexes and what are indexes at all. Why should one even bother about such a thing? OK, what do you think are other things which rubyists must know? What technical things rubyists should know to do his or her job better?

There’s a couple of things. One I think is Ruby the language itself. Learn the language very well. Other thing is learning UNIX well.

You are the first speaker I’ve interviewed who said you should know UNIX. Personally, I came to Ruby world from UNIX world. I was doing Linux, FreeBSD and tons of things with Perl. I came to Ruby as yet another Perl to do my sysadmin things, and then I’ve found it as a web language as well. You’re saying we should know UNIX. Why and how?

It’s important to learn about POSIX standards and the way they interact with the operating system because you gonna run into that stuff when you will start scaling. You…

… have to know who is General Failure and why he’s reading my file?

Haha, yes! You need to know what makes the difference in performance. Maybe, you don’t need to specifically memorize it but you need to know that they [syscalls — P.A.] exist and how to google them because you gonna run into this type of stuff. They are going to impact you because you are deploying your application to UNIX server so you need to learn how your application is going to interact with the OS that it’s being deployed to. Other important thing is if you learn those UNIX skills, you can take them to other languages too. If you ever have any problems, you can start there. That’s one thing I recommend people learn.

Do you think is it good for a rubyist to know another language? Is it possible to be a good Ruby programmer without knowing something outside Ruby alone?

That’s a good question. Honestly, I don’t know. All good Ruby programmers I know do know other languages. But I don’t know if you need to learn other languages to become a good Ruby programmer. I think it just happens that people learn other languages.

That’s good observation! By the medical point of view, the more languages people know, the farther their Alzheimer goes.


After 40 you have to think about those things…

I’m getting close to 40s! I need to know that!

Let’s talk about Ruby itself. Ruby is a language with a great past. Is it also a language with a future? Week ago, I was at Saint Petersburg at the biggest IT conference I’ve ever seen in Russia. Saint Petersburg’s Ruby community wasn’t represented at the conference. I constantly had to do a big deal of apology for Ruby: that Ruby isn’t THAT dead, that Ruby is a language somebody still writes. Ruby has some kind of the  best web frameworks, things like that. Every major language on the market now has something as web development tools. Go, Rust, whatever. What is Ruby’s place in this ecosystem and does “Ruby with great past” have a future?

I think there’s couple of aspects answering that question. There are a lot of different languages that have web frameworks but I still believe that if you look at them from the perspective of developer ergonomics, Ruby is still going to come on top. It’s easy to use and easy to get something shipped. The problem is that it’s not new and shiny anymore. People wanna hop onto the next bandwagon. They wanna be on the next-to-Rails train.

They want a smell of a new car!

Yes! For future… There’s a lot of new developments go in Ruby, especially with a JIT and what Koichi works on, guilds. But the thing is, I would caution and say that Ruby definitely has a future but that’s the thing we all have to work for. If we put in an effort, the future’s definitely there.

Does Ruby have any perspective in areas other than web development? Or, do you know any examples where Ruby is being used these days outside of web development?

That’s a good question! It’s hard for me to answer because I’m so into… I’m only look at web development.

I’m asking because it’s pretty interesting to me as well. Guys of Python community like to boast their scientific success.

I know there’s a group working on Ruby scientific tools. But I think the main “other” application the people use Ruby for is systems administration.

How can we attract developers of other languages to our community?

That’s really good question! I think we just need to keep focusing on developer’s ergonomics, making developing web applications as easy as possible. We need to focus on lowering a bar for new developers who come onboard and write web applications. That’s the way we’ll get more new developers.

We came to this kind of a holy war question, about JavaScript. You know, they say that everything that could be rewritten in JavaScript will be rewritten in JavaScript. Do you feel like Rails will be also rewritten in JavaScript? We spoke about ergonomics of Ruby development. It’s best thing about Rails. One of the best known Russian programmers said that “many languages are good, but only Ruby has Rails”. But JavaScripters tend to question this situation. How can we battle with JavaScript? Or should we have symbiosis with that?

It’s very true that only Ruby has Rails. If you look at the web development frameworks for JavaScript, I don’t think that they compare very well to Rails. In terms of developer’s ergonomics. But the thing is - since we’re writing web applications, we need to work with JavaScript. We need to be a part or JavaScript community. It’s good for us to have symbiosis with that. If you can run any language on a server, why would you peak JavaScript? Haha! But it’s a fine language, I think, we need to work symbiotically. We still have developer’s ergonomics on our side, it’s still great at Rails community. So, you came to an IT conference and you had to represent Ruby there?

That was very informal, because I even didn’t have a t-shirt of my company or language. So I've just found a brightest group of young people which appeared to be the pythonists and we started chatting.

It’s better for us if we work together with other languages rather than being rival with them. Personally, I think programming in Ruby is so much easier and nicer than other languages. Why not? We’re talking about other programming languages and whether you should know them. I do think it’s important that Ruby developers learn other programming languages. Something like Java, Haskell, or something other functional like Elixir or Lisp, something like that. I think it's good to learn different paradigms because once you learn it, you can steal it and use it in your programming language. Nice thing about Ruby is that we can use different programming languages’ techniques in our programs.

Yes, we have, for example, instruments for functional programming or doing map/reduce/whatever.   

Yes, we’re able to use those things. If you use the language that encourage those, maybe you’ll learn a better way to do on the problem that you are trying to solve. I don’t know if you have to learn other programming languages to be good at Ruby, but learning other ones definitely helps me for sure. Honestly, I spend 50% of my time programming in C. Haha!

C makes your fingers stronger!

I program in C so others can program in Ruby. Haha!

Ruby internals are written in pure C, not ++?

Just C. It would be nice if more will be written in Ruby but honestly some of core stuff, for performance, we have to write it in C. One of the things I do is, we’re trying to do more memory profiling. So, I’m working at tools for doing memory profiling in Ruby. Since all the internals are in C, I have to write tools in C. I do a lot of C at work.

How does it go in Ruby with FFI and such?

FFI works pretty well. If you have a C library that only has one or two functions that you need… If it gets more complicated… It’s a lot harder. If you’re using FFI, you’re essentially writing C code that looks like Ruby. You still have to do weird stuff like memory management. I find personally, it’s easier to switch between those worlds if I use C to do the memory management, etc. and turn over to Ruby in other cases.

In Ruby, do we have interfaces to other languages?

Some interfaces with the JavaScript. I saw a guy who was doing a scientific work so he was interfacing with Python.

They’re interfacing directly with language runtime?

Yes, exactly. Not like shelling out or anything like that… His project is very experimental. When he’s giving demos, he says that “These things are working, but they are able to crash!”

I know a bunch of known ruby guys who went out to make Rust language. Why do you think, the people went there and how are they doing there?

I like Rust, I think it’s very good language. The reason why people are going to Rust…  because they want to have a systems programming language that has more safety than C does. It would be really, really awesome if Ruby will be rewritten with Rust. I’m personally a huge fan of Rust, I really like Rust.

Why could it be useful? Is it safer or quicker, or what?

I think it’s safer. I’m not sure whether or not it has better optimizations than C, but it’s definitely safer. So, that’s the thing I like upon it. When I’m writing C code, I’m pretty sure it won’t go SEGV but not that sure. But when I write rust code, I’m a lot more confident. When I’m writing C code I’m pretty sure it’s not gonna leak memory. With a Rust it’s clear you’re not gonna leak memory. That’s why I personally like Rust rather then C. I started learning Rust because I wanna write Ruby extensions with Rust. There’s a project called ‘Helix’, that lets you do that exactly. Whenever I write the C code it’s mostly like “OK, I have a C library and I have to access it from Ruby, writing a little bit of glue code.” Using Rust is overkill for something like that. In my ideal world, everything, whole system stuff will be re-written with Rust. Rust will be our new C. If you need something done quickly, you will write in Ruby. The operating system will be done in Rust. That will be awesome.

Is Rust mature enough to do the job?

I don’t know. I think so. Mozilla using it, they are pretty happy with it.

With Rust, what a chance do I have to see the registers of my CPU?

Haha, I don’t know! Hopefully low! It’s not fun when you see that information.

Especially, when you run something within the browser.

Yes. You get a crash notification and you like: “OK”. Haha! We got some C++ stuff at work and sometimes when I get those crash I just think: ”Huh…” Haha!

“I should program in the language, not macro assembler!” — That was favorite joke when I switched from C to Ruby…

You’re actually right! Whenever I’m writing in C, that’s what I have to think about. I’m not actually thinking about the thing that I’m doing. With Ruby I don’t have to think about that [low level — P.A.] stuff. I just focus on a logic of a program and I’m done with my job. That’s one of the reason I love the language so much! When I was a Java programmer on Java 1.3, that was before they had generics. Any time you had to write something like a map, like, say, collection, iterator, you’ll have to say “iterator-dot-next”, and then you’ll have to cast the thing, because collection didn’t know what was inside of it. Then you do the operation that you wanted to do. All the stuff around for just writing map. Then I’ve started learning Ruby, doing map in it was very similar to Perl…

… Oh, what a magic! I have an object right here with exact type I need?

Yes, exactly. In Java, I had to write 15 lines of code to do what I can do with one line at Ruby. If I was writing in Ruby, I was done with my job right now! Instead of writing all this crap! That realization made me incredibly depressed at work. I’ve spent so many hours on stuff I didn’t need to be doing!

Existential horror!

Yes, exactly! That was a turning point. I need to find a job programming Ruby. I can’t do this Java stuff for the rest of my life!

Can you tell that working in Ruby makes the programmer’s mind better?

I think if you’re able to spend more time focusing on high level tasks, goals of the program, then it helps you become better at abstract thinking. You get more practice thinking of the system as a whole rather than of tiny parts of the program. Like in C, I have to think about all those tiny little  things rather than the problem that I solve. In essence, you get more practice solving problems or solving high level tasks. I think it might make you better programmer.

I remember my own impression when I started back in some 90s. I tried to master OOP. I tried to do things at C++. I read the books and I’ve understood that “holy trinity of OOP”. Then I found myself at the beginning of macro assembler stuff again. Then I’ve tried to do Java and I did Perl for a living. But finally, I’ve found that only in Ruby understood what OOP means.

That makes sense. If you’ll think about other OO languages like C++, Java, that generation of OO languages. Not everything was an object. You still had ints, for example. You still had primitives and you had to deal with them differently than like with an object. In Ruby, really everything is an object. You have to do OOP. You get more practice, that’s making a lot of sense. I really didn’t think about it before you’ve brought it up.

The language was engineered so smoothly, that it just makes you thinking in this direction. That shapes your mind. Syntax explains what you’re doing.

I did OO stuff in perl. That’s mostly hack for OO-like stuff. Java, of course, does OO stuff. but it has non-object stuff too. Ruby is a first language where everything is really an object.

How would you encourage young programmers and how would you encourage older programmists too?

That’s good question! I think this is for both young and old rubyists. I personally think that Ruby is the only programming language that when I use it’s actually fun. For young programmers, who done other languages - give Ruby a try, because you’ll actually have good time. For older programmers - it’s nice to use other languages, so you can get a perspective how fun Ruby is, because if you use it long enough you might forget. When you go use something else, you will say - wow, I was having good time with Ruby!

I do some short switches to other languages for a weekend. After the weekend, I go back to work, open my Emacs with Ruby and I say: “Wow! What a glory to return back!”

Yes, I think it's good to go to other languages, do some work with them, get some perspective. It makes me better to come back. I feel like I’m coming home.

Meet Aaron and ask a question in person at Ruby Russia 2018!

Questions were asked by Pavel Argentov, developer from Evrone.