No release in over 3 years
Scans your views and helpers for icon() calls, subsets FontAwesome WOFF2 fonts via pyftsubset, and generates minimal CSS. Includes a Puma plugin for development watch mode, a Rails view helper, and a rake task that hooks into assets:precompile.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 5.0

Runtime

 Project Readme

FontAwesome Subsetter

A Rails gem that tree-shakes FontAwesome 7 — scans your views and helpers for icon() calls, subsets WOFF2 font files to include only used glyphs, and generates minimal CSS.

Requirements

  • FontAwesome files in vendor/fontawesome/ (metadata, scss, webfonts)
  • pyftsubset (from fonttools): pip install fonttools brotli
  • sass-embedded gem for SCSS compilation

Installation

Add to your Gemfile:

gem "fontawesome_subsetter"

Then run bundle install.

Setup

Directory Structure

The gem expects FontAwesome files in your project at:

vendor/
  fontawesome/
    metadata/
      icons.yml
    scss/
      variables.scss
      functions.scss
      mixins.scss
      core.scss
      animated.scss
      icons.scss
      solid.scss
      regular.scss
      ...
    webfonts/
      fa-solid-900.woff2
      fa-regular-400.woff2
      fa-brands-400.woff2
      fa-duotone-900.woff2
      fa-thin-100.woff2

Features

1. Icon Helper

The gem provides an icon helper available in all views:

= icon(:fas, :download, "Download", class: "mr-1")
= icon(:far, :check)
= icon(:fab, :github)

2. Puma Plugin (Development Watch Mode)

Add to your config/puma.rb:

if ENV.fetch("RAILS_ENV", "development") == "development"
  plugin :fontawesome_subsetter
end

This watches app/views/, app/helpers/, and app/components/ for changes and automatically rebuilds subsetted fonts.

3. Rake Task (Deploy)

The gem automatically hooks into assets:precompile:

rake assets:precompile  # fontawesome:subset runs first

You can also run it manually:

rake fontawesome:subset

Configuration

# config/initializers/fontawesome_subsetter.rb
FontawesomeSubsetter.configure do | config |
  # Paths to scan for icon() calls (defaults shown)
  config.scan_globs = ["app/views/**/*.slim", "app/helpers/**/*.rb"]

  # Regex to match icon() calls (default shown)
  config.icon_regex = /icon\(\s*:(?<prefix>fas|far|fab|fad|fal|fat)\s*,\s*:(?<icon>[\w_\-]+)\b/

  # Override default paths (optional — defaults use Rails.root)
  # config.meta_path = Rails.root.join("vendor", "fontawesome", "metadata", "icons.yml")
  # config.fonts_dir = Rails.root.join("vendor", "fontawesome", "webfonts")
  # config.build_dir = Rails.root.join("app", "assets", "builds")

  # Custom SCSS template (optional — receives @styles hash, must return SCSS string)
  # config.scss_template = ->(styles) { "..." }
end

Deploying with Kamal (Docker)

pyftsubset must be available during assets:precompile in your Docker build stage. Add the following to the build stage of your Dockerfile:

# In the build stage, install pyftsubset for font subsetting
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y python3 python3-pip python3-venv pipx && \
    pipx ensurepath && \
    pipx install fonttools && \
    pipx inject fonttools brotli && \
    ln -s /root/.local/bin/pyftsubset /usr/local/bin/pyftsubset && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

Font subsetting runs automatically during assets:precompile, so no additional Dockerfile steps are needed — just make sure the line above appears before your RUN ... assets:precompile step.

The final (runtime) stage does not need pyftsubset; subsetted fonts are already baked into the image.

License

MIT — Copyright (c) 2026