# sprockets-rails: the Rails side of the Sprockets asset pipeline

> sprockets-rails is the MIT licensed gem that wires the Sprockets asset pipeline into a Rails application, supplying the precompile, clean and clobber rake tasks and the config.assets options that decide how assets are found and served. Its API is small, and most of its decisions are visible in how the manifest and the environment are ordered.

**rails/sprockets-rails** — Sprockets Rails integration

- Repository: https://github.com/rails/sprockets-rails
- Stars: 593 · Forks: 244
- Language: Ruby
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/rails-sprockets-rails

## A railtie, not an asset manager

sprockets-rails provides the Sprockets implementation for the Rails 4.x and beyond asset pipeline. That description sounds like a wrapper, and it is: the asset compilation itself is done by Sprockets, the separate `rails/sprockets` project, and this gem is the glue that turns Sprockets into a Rails subsystem.

The glue is a railtie, and installing it is one line in the Gemfile:

```ruby
gem 'sprockets-rails', :require => 'sprockets/railtie'
```

The `:require` is not incidental. A Rails application that uses Bundler's automatic require would otherwise load every gem in the bundle, and Sprockets pulls in a considerable amount of machinery that most applications never need at boot. The alternative route is to require `sprockets/railtie` yourself in `config/application.rb`, and the documentation names that as the option for applications that have Bundler auto-require disabled.

What the railtie provides is the set of things a Rails application expects an asset system to supply: the configuration surface under `config.assets`, the three deployment rake tasks, the view helpers that generate the URLs, and the behaviour that decides whether a request for an asset is answered from the precompiled manifest or by compiling on the fly.

The scale is worth noting. The repository is small, with `lib/`, `test/`, `gemfiles/` for testing against dependency versions, a `sprockets-rails.gemspec`, a `Rakefile` and a `.devcontainer/`. There is no asset compilation code here, because all of it lives in Sprockets itself. What lives here is the set of decisions about how Rails should use it, and those decisions are what the rest of this article is about.

## Three rake tasks, and the rolling deploy problem

The deployment surface is three tasks, and the difference between them is where most of the real behaviour of this gem sits.

`rake assets:precompile` is the deployment task, and it compiles any assets listed in `config.assets.precompile` to `public/assets`. `rake assets:clean` only removes old assets, keeping the most recent 3 copies, and the documentation explains why that matters: it is useful when doing rolling deploys that may still be serving old assets while the new ones are being compiled. `rake assets:clobber` nukes `public/assets`.

The clean task is the interesting one, and the number 3 is a deliberate choice rather than a default that was never thought about. A rolling deploy means that for a period, some servers are running the old release and some the new one, and the old release's HTML references the old digested filenames. If the deploy deleted every asset from `public/assets` before the new build finished, those old pages would reference files that no longer exist and users would see broken stylesheets and scripts. Keeping a few generations of assets means a page served by an older application instance still finds its files.

That default is also why the task generator exists. The documentation says that if the basic tasks do not do all that you need, it is straightforward to redefine them, and you can also use the built in task generator:

```ruby
require 'sprockets/rails/task'
Sprockets::Rails::Task.new(Rails.application) do |t|
  t.environment = lambda { Rails.application.assets }
  t.assets = %w( application.js application.css )
  t.keep = 5
end
```

The `keep` setting is how you change the retention from three copies to five, and the `assets` list is how you compile a specific set rather than everything the configuration names.

One more detail matters for anyone writing their own tasks: each asset task will invoke `assets:environment` first, which by default loads the Rails environment, and you can override that task to add or remove dependencies for a specific compilation environment. That is the seam to use if precompiling in a deploy script should not boot the whole application.

## The config.assets options that decide what gets built and served

The initializer options are the real interface of this gem, and a few of them change behaviour in ways that are easy to get wrong.

`config.assets.precompile` defaults to `application.js`, `application.css` and any other non-js/css file under `app/assets`, and you add to it to compile more assets on deploy. `config.assets.paths` adds load paths, and Rails already includes `app/assets`, `lib/assets` and `vendor/assets` for you, with plugins expected to add their own.

`config.assets.compile` is the switch between development and production behaviour. It enables the Sprockets compile environment, and if it is disabled, `Rails.application.assets` will be `nil` to prevent inadvertent compilation calls. The documentation is explicit about the consequence: view helpers will depend on assets being precompiled to `public/assets` in order to link to them, and initializers that expect `Rails.application.assets` during boot should be reaching the environment inside a `config.assets.configure` block instead.

That configure block is where the environment is actually manipulated, and it is the place to set compressors and register processors:

```ruby
config.assets.configure do |env|
  env.js_compressor  = :uglifier # or :closure, :yui
  env.css_compressor = :sass   # or :yui

  require 'my_processor'
  env.register_preprocessor 'application/javascript', MyProcessor

  env.logger = Rails.logger
end
```

The other options are smaller. `config.assets.digest` adds fingerprints to asset filenames, `config.assets.debug` includes a source map with each asset, `config.assets.prefix` defaults to `/assets` and changes the directory assets are compiled to, and `config.assets.quiet` suppresses logger output for asset requests. `config.assets.version` is a custom cache buster string, and changing it causes all assets to recompile on the next build, which is the documented way to invalidate everything after a plugin changes the load paths.

Two of the remaining options are about missing assets. `config.assets.unknown_asset_fallback` defaults to `true`, meaning a result is returned even when the requested asset is not in the pipeline, and setting it to a falsey value raises an error instead. `config.assets.check_precompiled_asset` is enabled by default, and when enabled an exception is raised for missing assets.

## resolve_with decides whether the manifest or the environment answers first

The most interesting option is `config.assets.resolve_with`, a list of `:environment` and `:manifest` symbols that defines the order in which assets are looked for, with the manifest checked first, then the environment, or the environment only. The documentation gives the three configurations explicitly:

```yaml
# Dev where debug is true, or digests are disabled
%i[ environment ]

# Dev default, or production with compile enabled.
%i[ manifest environment ]

# Production default.
%i[ manifest ]
```

The rules behind those three are worth spelling out, because the list is generated rather than chosen. By default the manifest is checked first if asset digests are enabled and debug is not enabled, and then the environment is checked if compiling is enabled. In development, where debug mode is normally on, there is no manifest worth consulting, so the environment answers. In production, with digests on and compilation off, only the manifest is consulted, which means an asset that was not precompiled is not found rather than being compiled on the fly during a request.

There is one more case. If the resolver list is empty, for example when debug is true and compile is false, the standard Rails public path resolution is used, which is the behaviour where a missing asset quietly links to a file in `public/`.

The related option `config.assets.resolve_assets_in_css_urls` defaults to `true` and registers a CSS postprocessor that resolves assets referenced in `url()` calls and replaces them with the digested paths, so a background image referenced from a stylesheet gets the same fingerprint treatment as a script tag.

## Decisions inherited from the Rails 3.x rewrite

The README keeps a section titled Changes from Rails 3.x, and it is worth reading because most of that section still describes how the gem behaves today.

Only digest filenames are compiled, and static non-digest assets should simply live in `public/`. Unmanaged asset paths and urls fall back to linking to `public/`, and the stated purpose is to make it easier to work with both compiled assets and simple static ones. The side effect is that there will never be any asset not precompiled errors when linking to missing assets, they will just link to a public file which may or may not exist. That is a deliberate trade, and it is the one most likely to surprise someone moving from a different pipeline: the failure is silent.

JavaScript and CSS compressors must be explicitly set, because magic detection was removed to avoid loading compressors in environments where you want to avoid loading any of the asset libraries. Assign `config.assets.js_compressor = :uglifier` or `config.assets.css_compressor = :sass` for the standard compressors.

The manifest also changed shape. The manifest file is now in a JSON format, and since it lives in `public/` by default, the initial filename is randomised to obfuscate public access to the resource. If you use `config.assets.manifest` it must include the manifest filename, for example `Rails.root.join('config/manifest.json')`, and it cannot be a directory.

One last detail for anyone with a long-lived deployment script: the two cleanup tasks behave differently on purpose. `rake assets:clean` is a safe cleanup that only removes older assets that are no longer used, while `rake assets:clobber` nukes the entire `public/assets` directory, and the clean task allows for rolling deploys that may still be linking to an old asset while the new assets are being built.

## Optional plugins, and where the gem fits

The complementary plugin section is short and says something useful. The plugins listed are `coffee-rails` and `sass-rails`, and the note is that these plugins are optional, that the core coffee-script, sass, less, uglify and many more features are built into Sprockets itself, and that many of these plugins only provide generators and extra helpers, so you can probably get by without them.

That is a useful corrective for anyone arriving from older versions of the Rails asset pipeline documentation, where the sass and coffee plugins were part of the standard setup.

On upkeep, the repository is not archived and the last push was on 2026-08-19, but the release history is older: v3.5.2 on 2024-07-31, v3.5.1 on 2024-06-07 and v3.5.0 on 2024-06-06. A gem that is still receiving pushes while its last release is two years old is a signal that the maintenance is on the branch rather than on the release line, which matters if you pin a version.

The licence is MIT, with the licence text in `MIT-LICENSE`, so there is no friction in using it in a commercial application.

The strategic question for a new application is whether to adopt this at all. The gem is the integration layer between Rails and Sprockets, and its value is highest for an application that already has an asset build in place and wants Rails to manage it with the standard rake tasks and digesting. For a new application on a recent Rails version, the default asset pipeline that Rails ships with is the path with fewer moving parts, and reaching for sprockets-rails means taking on the configuration decisions described above, including the ones about compressors, the manifest and the resolver order.

## Conclusion

sprockets-rails suits a Rails application that is staying on the Sprockets asset pipeline and wants the standard deployment tasks, digesting and the well known configuration surface, particularly a team that has to support a rolling deploy where old and new asset URLs are served at the same time. It does not suit a greenfield Rails application that would rather use the default asset pipeline that later Rails versions ship with, and it is not a bundler replacement, since it only manages the assets that Rails asks it to compile. Before changing the configuration, read the resolve_with ordering and the assets:clean behaviour, because those two decide what a deploy leaves on disk and which URLs resolve.

## FAQ

### How do I install sprockets-rails in a Rails application?

Add `gem 'sprockets-rails', :require => 'sprockets/railtie'` to the Gemfile, or require `sprockets/railtie` yourself in `config/application.rb` if you have Bundler auto-require disabled.

### What is the difference between assets:clean and assets:clobber?

`rake assets:clean` only removes old assets and keeps the most recent 3 copies, which is what makes rolling deploys safe while old asset URLs are still being served. `rake assets:clobber` removes the whole `public/assets` directory.

### What does config.assets.resolve_with control?

It is a list of `:environment` and `:manifest` symbols defining the order in which assets are looked for. By default the manifest is checked first when digests are enabled and debug is not, then the environment when compiling is enabled, and if the list is empty the standard Rails public path resolution is used.

### How do I set a JavaScript and CSS compressor in sprockets-rails?

Compressors must be set explicitly, because magic detection was removed. Assign `config.assets.js_compressor = :uglifier` or `config.assets.css_compressor = :sass`, or do it inside a `config.assets.configure` block where you can also register preprocessors and set the logger.

### Do I still need sass-rails and coffee-rails with sprockets-rails?

Not for the core features. The documentation notes that coffee-script, sass, less and uglify support are built into Sprockets itself, and that plugins such as sass-rails and coffee-rails mostly provide generators and extra helpers, so you can probably get by without them.

## Sources

- [Issues](https://github.com/rails/sprockets-rails/issues)
- [License: MIT](https://github.com/rails/sprockets-rails/blob/master/LICENSE)
- [rails/sprockets-rails on GitHub](https://github.com/rails/sprockets-rails)
- [README](https://github.com/rails/sprockets-rails/blob/master/README.md)
- [Releases](https://github.com/rails/sprockets-rails/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rails-sprockets-rails
