Andrew Timberlake Andrew Timberlake

Hi, I’m Andrew, a programmer and entrepreneur from South Africa,
building Mailcast for taking control of your email.
Thanks for visiting and reading.


Use Font Awesome icons in Phoenix with Tailwind 4

If you are using Tailwind 3, please see this post

It’s great that Phoenix comes with Heroicons support out the box, but I use Font Awesome and wanted to use those in the same way. This post will show you how you can swap out Heroicons and make a few changes so that the .icon component works with Font Awesome instead.

There are a few ways to use Font Awesome icons but this post will show you how to use the SVG icons hosted within your project in the same way that Heroicons work.

Step 1. Download the SVG files

Go to the Font Awesome download page and download the “version for the web” you’re going to use.
For this example, I’ll download the Free for Web version.

Step 2. Save the icons to your assets/vendor directory

  1. Delete the directory assets/vendor/heroicons
  2. Unzip the Font Awesome download and copy the contents of svgs/ into assets/vendor/fontawesome so you have:
    assets/vendor/fontawesome/brands
    assets/vendor/fontawesome/regular
    assets/vendor/fontawesome/solid

If you’re using the pro version, then copy in the SVG directories you want to use.

Step 3: Create a fontawesome.js plugin

Copy vendor/heroicons.js to vendor/fontawesome.js and make the following changes:

  1. Change the path to the icons "../../deps/heroicons/optimized" to "fontawesome/svgs"
  2. Change the icon variants to match the Font Awesome icons. In this case we’re using regular as default, and changing -mini to -brand. You can add other Fonteawesome variants here as well, like -light.
  3. Change all occurrences of hero to fa

The icon naming will change from hero-<name> to fa-<name>, hero-<name>-mini to fa-<name>-brand, and hero-<name>-solid to fa-<name>-solid.

@@ -1,16 +1,15 @@
-// A Tailwind plugin that makes "hero-#{ICON}" classes available
+// A Tailwind plugin that makes "fa-#{ICON}" classes available
 const plugin = require("tailwindcss/plugin")
 const fs = require("fs")
 const path = require("path")

 module.exports = plugin(function({matchComponents, theme}) {
-  let iconsDir = path.join(__dirname, "../../deps/heroicons/optimized")
+  let iconsDir = path.join(__dirname, "fontawesome/svgs")
   let values = {}
   let icons = [
-    ["", "/24/outline"],
-    ["-solid", "/24/solid"],
-    ["-mini", "/20/solid"],
-    ["-micro", "/16/solid"]
+    ["", "/regular"],
+    ["-solid", "/solid"],
+    ["-brand", "/brands"],
   ]
   icons.forEach(([suffix, dir]) => {
     fs.readdirSync(path.join(iconsDir, dir)).forEach(file => {
@@ -19,7 +18,7 @@ module.exports = plugin(function({matchComponents, theme}) {
     })
   })
   matchComponents({
-    "hero": ({name, fullPath}) => {
+    "fa": ({name, fullPath}) => {
       let content = fs.readFileSync(fullPath).toString().replace(/\r?\n|\r/g, "")
       content = encodeURIComponent(content)
       let size = theme("spacing.6")
@@ -29,9 +28,9 @@ module.exports = plugin(function({matchComponents, theme}) {
         size = theme("spacing.4")
       }
       return {
-        [`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`,
-        "-webkit-mask": `var(--hero-${name})`,
-        "mask": `var(--hero-${name})`,
+        [`--fa-${name}`]: `url('data:image/svg+xml;utf8,${content}')`,
+        "-webkit-mask": `var(--fa-${name})`,
+        "mask": `var(--fa-${name})`,
         "mask-repeat": "no-repeat",
         "background-color": "currentColor",
         "vertical-align": "middle",

Step 4: Change the reference from heroicons to fontawesome in main.css

@@ -6,7 +6,7 @@
 @source "../js";
 @source "../../lib/trelany/web";

-@plugin "../vendor/heroicons";
+@plugin "../vendor/fontawesome";
 /* daisyUI Tailwind Plugin. You can update this file by fetching the latest version with:
    cd assets/vendor && curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui.js && cd ../../
    Make sure to look at the daisyUI changelog: https://daisyui.com/docs/changelog/ */

Step 5: Modify your components file.

Do a search and replace across your core_components.ex file changing "hero-" to "fa-". The most important change is the icon/1 function which needs to match on "fa-". Note, not all the icons have a direct replacement so you may still need to find those icons and give them names that match the Font Awesome library.

@@ -417,13 +417,13 @@ defmodule MyAppWeb.CoreComponents do

   ## Examples

-      <.icon name="hero-x-mark-solid" />
-      <.icon name="hero-arrow-path" class="w-3 h-3 ml-1 motion-safe:animate-spin" />
+      <.icon name="fa-x-mark-solid" />
+      <.icon name="fa-arrow-path" class="w-3 h-3 ml-1 motion-safe:animate-spin" />
   """
   attr :name, :string, required: true
   attr :class, :string, default: nil

-  def icon(%{name: "hero-" <> _} = assigns) do
+  def icon(%{name: "fa-" <> _} = assigns) do
     ~H"""
     <span class={[@name, @class]} />
     """

Step 6: Cleanup

Remove :heroicons from your mix.exs file.

Step 7: Use Font Awesome

You can now use any Font Awesome icons in your code with <.icon name="fa-rocket-solid" />

I hope that helps.

09 Apr 2025

I’m available for hire, whether you need an hour to help you work through a particular problem, or help with a larger project.