LocoMotion now renders every icon through a small, pluggable
icon engine built on the icons
gem — so you can use Heroicons, Lucide, Phosphor, and more from one API.
Earlier versions of LocoMotion depended on rails_heroicon, which shipped
the entire Heroicons set inside the gem and exposed a hero_icon helper.
That has been replaced by the loco_icon engine: LocoMotion bundles only
a tiny set of icons and resolves everything else from the icons you sync
into your own app — the same way Tailwind only
ships the CSS you actually use.
This guide covers everything you need to change. Most apps only touch two
things: run one sync command, and rename hero_icon to loco_icon.
LocoMotion bundles just the handful of icons its own components need
(check, x-mark, trash, and the calendar chevrons). Everything else —
including most of Heroicons — now lives in your app. Sync the full
Heroicons set once and commit the SVGs:
bin/rails loco_motion:icons:add heroicons
Prefer to ship only what you use? Run the treeshaking sync instead — it scans your app (and a configurable safelist) and vendors only the icons you reference:
bin/rails loco_motion:icons:sync
Both commands give each library its own folder —
app/assets/svg/icons/<library>/<variant>/ (e.g.
app/assets/svg/icons/heroicons/outline/). Commit the SVGs; they render as
inline <svg> with no runtime dependency on any gem.
hero_icon with loco_iconThe hero_icon helper (and the heroicon alias) have been removed. Rename
calls to loco_icon:
-# Before
= hero_icon("academic-cap")
-# After
= loco_icon("academic-cap")If a call specified a variant or library, fold it into the icon name as a
token rather than a separate option:
hero_icon("bolt", variant: :solid) becomes loco_icon("bolt/solid").
See step 5 for the full token format (it's also what the sync scans).
Hero::IconComponentThe Hero::IconComponent wrapper has also been removed. Anywhere you
rendered it directly, use the loco_icon helper instead:
-# Before
= render(Hero::IconComponent.new(icon: "star"))
-# After
= loco_icon("star")Options like icon:, left_icon:, right_icon:, and the Timeline event's
middle_icon: now resolve through the same engine. They work with no
setup for the bundled icons (LocoMotion's chrome plus the standard alert
icons), but any other name — like shopping-cart — must be synced first
(see step 1):
= daisy_alert(icon: "information-circle") -# bundled, no sync
= daisy_button("Cart", icon: "shopping-cart") -# needs a syncSpecify a library or variant with a token — one string in the form
library:name/variant, the same way Iconify
names icons. The treeshaking sync scans your source for these strings, so
keeping the library and variant in the token (rather than in separate
options) is what lets loco_motion:icons:sync find and vendor the exact
icons you use:
= loco_icon("bolt/solid") -# a variant
= loco_icon("lucide:heart") -# another library
= loco_icon("phosphor:gear/bold") -# library + variantAdd more libraries the same way you added Heroicons — run
bin/rails loco_motion:icons:list to see the options.
loco_motion:icons:add heroicons (or :sync) once; commit the SVGs.hero_icon / heroicon to loco_icon.Hero::IconComponent with loco_icon.
Create virtual credit / debit cards to keep your real info safe.
Get $5 when you sign up — free to start!
Everything you need to grow your business with confidence!
CRM, Lead Generation, Project Management, Contracts, Online Payments, and more!
The ads above are affiliate links to products I regularly use and highly
recommend.
I may receive a commission if you decide to purchase.