FullstackPhoenix

Bootstrap Icons in Phoenix and Tailwind

phoenixtailwindiconsui

You're three weeks into the dashboard and the icons are already inconsistent. Heroicons for the nav, an inline SVG someone copied from the design file in the empty state, a font-awesome class in the settings page. Each one ships its own assets, the bundle is bigger than it should be, and the visual language drifts every week.

This feature pulls the entire Bootstrap Icons set into your Tailwind build as CSS utility classes. There is no JS at runtime, no extra component to import, and no decision to make about which icon library "wins" — the icons sit alongside your existing Tailwind utilities and the existing <.icon> component you already use.

One icon set, no runtime cost

Inconsistent iconography reads as sloppiness even when nothing else about the UI is wrong. Having a single, large, well-named set available as utility classes makes the right choice the easy choice. The fact that the icons are rendered as CSS-only background images means there is no extra request, no extra JS, and no extra component plumbing — just a class.

What This Feature Adds

  • A mix.exs entry for {:twbs_icons, github: "twbs/icons", sparse: "icons", tag: "v1.11.3", app: false, compile: false, depth: 1} so the repository is fetched as a sparse checkout (no Ruby, no JS, just the SVGs)
  • A Tailwind plugin (added to assets/tailwind.config.js) that walks the icons directory and emits a bi-<name> utility class per SVG using a data URI
  • An extension to the existing core_components.ex icon/1 function so <.icon name="bi-…"> is routed to the new classes alongside Heroicons

How It Fits Into Your Phoenix Application

The icons become part of the Tailwind build, which means they are scanned and tree-shaken like any other Tailwind utility — only the icons you actually reference in your templates end up in the final CSS. There is no JS hook to register and no LiveView assigns to thread through:

<.icon name="bi-house" class="size-5 text-blue-500" />
<.icon name="bi-envelope-fill" class="size-4" />
<span class="bi-gear size-6" />

The core_components.ex icon/1 function continues to handle Heroicons as before, so this feature adds to the set rather than replacing it.

Installation Notes

  • No other feature is required. Bootstrap Icons stands on its own and does not depend on layouts, authentication, or any other feature in the catalog.
  • The twbs/icons sparse checkout is pinned to a specific tag in the manifest. Bump the tag in mix.exs when you want a newer set of icons.
  • The Tailwind plugin reads SVGs at compile time. Restart mix phx.server after install so the plugin loads.

Build This With Live SaaS Kit

Install saas_kit, then mix saaskit.feature.install bootstrap_icons to add 1,800+ icons as Tailwind utilities and stop sprinkling SVGs through your templates.