Quickly Migrate off Rails-assets.org - Vendor all source files

15th September 2021 – 436 words

Some of you might remember, there has been a time not long ago, where it was common to package frontend-code as “Bower” packages instead of NPM. In that time, before Webpack et. al., there was the pattern of using Rails Gems that include necessary frontend source files, like “angular-rails” or similar.

At that time, a helpful service by the community, rails-assets.org, emerged and automatically built Rails-gems from Bower packages. During recent months (or years event) Rails-assets had a couple of outages, that result in build failures, because dependencies could not be downloaded. After this happened a couple of times for us for one of our maintenance mode projects, we decided to simply vendor all the assets instead of relying on the Rails-assets Gems, which we also never updated anymore.

If you intend to maintain the application for a longer time, I would rather recommend to migrate to NPM/package.json instead, but for now, If you just want to get rid of Rails-assets, use this script:


1. Add vendor/assets/rails-assets/*/* to sprockets search path

Because Rails-assets-built Gems always have their assets-root-directory in “/assets” inside the Gem, we can use that level of directories to mimic the normal asset-lookup which loops over Gems.

Rails.application.configure do
  config.assets.paths += Dir["#{Rails.root}/vendor/assets/rails-assets/*/*"]

2. Copy all js/css etc. from the Gems into vendor/assets/rails-assets

Use the migrate.rb which is part of the Gist:

wget https://gist.github.com/zealot128/ff821bb338cf7bf5aa54b73eb18cafc2/raw/df1f2d80d79de901f2398e50dd765ff81bb42f8c/migrate.rb
ruby migrate.rb

This will create directories for each Rails-assets Gem under vendor/assets/rails-assets/ and copy over all the assets.

3. Remove rails-assets-* Gems from Gemfile and restart

Nothing to say, quickly done in 5min. There should be no other changes needed.

Reference: full migrate.rb:

#!/usr/bin/env ruby

require 'pry'

gems = `bundle list --paths | grep rails-assets`
gems.strip.split.each do |gem_path|
  base_path = Dir[gem_path + "/*.gemspec"].first.split('/').last.sub('.gemspec', '')
  target = "vendor/assets/rails-assets/#{base_path}"
  puts "copying #{gem_path} -> #{target}"

  Dir[gem_path + "/app/assets/*"].each do |source|
    FileUtils.cp_r(source, target)