rails-css_unused
Find ghost CSS classes in your Rails app: selectors that exist in your stylesheets but never show up in views or ViewComponents.
Pure static analysis — no browser, no headless Chrome. Built for the usual Rails paths (app/views, app/components, app/assets/stylesheets).
Requirements
- Ruby >= 3.1
- Rails >= 7.0 (via
railties)
Installation
# Gemfile
gem "rails-css_unused", group: :development
bundle install
Or install the gem directly (after it is published on RubyGems):
gem install rails-css_unused
During development of this gem itself, use a path install:
gem "rails-css_unused", path: "../rails-css_unused", group: :development
Usage
bin/rails css_unused:report
# or
bin/rails css_unused:ghosts
Example output:
rails-css_unused — Ghost Class Report
========================================
Project root: /path/to/myapp
Classes in stylesheets: 142
Classes referenced in views: 118
Ghost classes (in CSS, not in views): 24
Ghost classes:
legacy-banner
orphan-widget
...
What it scans
| Source | Paths (default) |
|---|---|
| Views | app/views — .html.erb, .html.haml, .haml, .erb, .slim |
| Components | app/components — same extensions |
| Styles | app/assets/stylesheets, app/assets/builds — .css, .scss, .sass |
| JS CSS | app/javascript — same stylesheet extensions |
Class detection in templates
class="foo bar"class: "foo",class: 'foo'class: %w[foo bar],class: ["foo", "bar"]tag.div ..., class: "foo"- Basic HAML
.class-namesegments
Configuration
# config/initializers/rails_css_unused.rb
Rails::CssUnused.configure do |config|
config.ignore_classes += %w[active hidden]
config.stylesheet_paths << "vendor/assets/stylesheets"
config.view_paths << "app/views/admin"
end
Optional config/application.rb hook:
config.rails_css_unused = ActiveSupport::OrderedOptions.new
config.rails_css_unused.ignore_classes = %w[sr-only]
Limitations
Static analysis cannot see everything:
- Dynamic classes —
class="<%= dynamic %>"may be missed or only partially detected. - Tailwind / utility frameworks — utilities are often generated at build time; many “ghost” hits are false positives unless you scan compiled
app/assets/buildsand tuneignore_classes. - JavaScript-added classes — Stimulus, React, or
element.classList.addare not scanned. - @extend / mixins — SCSS may define classes only used inside other rules; review before deleting.
Treat the report as a triage list, not an automatic delete command.
Programmatic API
Rails::CssUnused.ghost_classes
# => ["orphan-widget", "legacy-banner", ...]
Rails::CssUnused.report
Development
bundle install
ruby -Ilib -S rspec
Contributing
Bug reports and pull requests are welcome on GitHub.
Maintainers: see PUBLISHING.md for the release checklist and RubyGems publish steps.
License
The gem is available as open source under the terms of the MIT License.