Custom icons, duotone and the styling toolkit

Add your own icons, control duotone's two layers from CSS, use the sharp styles, and understand what the Icon Wizard and Pro+ packs change.

Your own icons

// Option A: upload the SVG in the kit UI. Simple, but your icon set now
// lives partly in a vendor's system and is not in your repository.

// Option B: define the icon in your own code. The definition is data, not
// markup, so it lives in version control and works with every SDK.
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';

export const faWarehouse: IconDefinition = {
  prefix: 'fas',
  iconName: 'warehouse',
  icon: [
    640,                                   // viewBox width
    512,                                   // viewBox height
    [],                                    // ligatures
    'e001',                                // unicode: use a private-use code point
    'M32 64C14.3 64 0 78.3 0 96v64c0 17.7 14.3 32 32 32H608c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32H32zm16 192v192H16c-8.8 0-16 7.2-16 16s7.2 16 16 16H624c8.8 0 16-7.2 16-16s-7.2-16-16-16H592V256c0-17.7-14.3-32-32-32H80c-17.7 0-32 14.3-32 32z'
  ]
};

// A multi-path icon: the last element is an array of path strings.
export const faServerStack: IconDefinition = {
  prefix: 'fas',
  iconName: 'server-stack',
  icon: [512, 512, [], 'e002', [
    'M64 32C28.7 32 0 60.7 0 96v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm0 192c-35.3 0-64 28.7-64 64v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V288c0-35.3-28.7-64-64-64H64z'
  ]]
};

// Register and use exactly like a standard icon
// library.add(faWarehouse, faServerStack);
Definition fieldMeaningRule
prefixThe style familyfas, far, fab, or your own
iconNameThe name used in markup and lookupsKebab-case, unique
Width, heightThe viewBox dimensionsMatch your path data exactly
LigaturesText shortcutsUsually empty for custom icons
UnicodeA code point for the font routeUse the private use area, e000-f8ff
PathOne string, or an array of stringsThe d attribute contents, without the element
Duotone second pathAn object with primary and secondaryOnly for duotone definitions
⚠️
Never redefine a code point that Font Awesome already uses, and never reuse one across your own custom icons. On the font route a collision shows the wrong glyph, and in a subset build it can collapse two icons into one. Stay inside the private use area and keep a comment recording which code belongs to which icon.

Duotone and its layers

<!-- A duotone icon has two paths. The second is the secondary layer,
     drawn behind, and both are themed with CSS custom properties. -->
<i class="fa-duotone fa-solid fa-house icon"></i>

<style>
  .icon {
    --fa-primary-color: #4c1d95;      /* the front layer */
    --fa-secondary-color: #c4b5fd;    /* the back layer */
    --fa-primary-opacity: 1;
    --fa-secondary-opacity: 0.6;
    --fa-size: 2rem;
  }

  /* Swap which layer gets which colour, without changing markup */
  .icon--swapped {
    --fa-primary-color: #c4b5fd;
    --fa-secondary-color: #4c1d95;
  }

  /* Animated duotone: the layers are real paths, so each can be animated */
  .icon--live {
    --fa-primary-opacity: 0.4;
    --fa-secondary-opacity: 0.25;
    transition: --fa-secondary-opacity 300ms ease;
  }
  .icon--live:hover { --fa-secondary-opacity: 0.9; }
</style>
<!-- On the web-font route there are no separate layers, so duotone is
     approximated with stacked elements. The SVG route needs only one element
     and two custom properties. -->
<span class="fa-stack fa-2x" aria-hidden="true">
  <i class="fa-duotone fa-solid fa-house fa-stack-2x" style="--fa-secondary-color:#c4b5fd"></i>
</span>

<!-- Pro+ adds Sharp and Sharp Duotone, which have their own family names and
     reject the rounded styles. Changing style is a class change: -->
<i class="fa-sharp fa-solid fa-house"></i>
<i class="fa-sharp-duotone fa-solid fa-house"></i>

<!-- Icon Wizard modifiers adjust an existing Pro icon: add a badge, cut a
     corner, add a slash. The result is a new icon definition you own, with
     its own name and code point. -->
StyleLayersFamilyAvailability
Solid1Font Awesome 7 Free, weight 900Free
Regular1Font Awesome 7 Free, weight 400Free, limited set
Light1Font Awesome 7 Pro, weight 300Pro
Duotone2Font Awesome 7 DuotonePro
Sharp Solid1Font Awesome 7 SharpPro
Sharp Regular / Light1Font Awesome 7 Sharp, weight 400 / 300Pro
Sharp Duotone2Font Awesome 7 Sharp DuotonePro+
Custom uploadedAnyYour kit's family nameKit-dependent
  • The duotone secondary layer sits behind the primary. If the icon looks flat, check that the secondary opacity is not zero and the secondary colour is not identical to the primary.
  • Custom-property transitions need @property declarations to interpolate; without them the change is instant rather than animated.
  • An uploaded custom icon is served from the kit CDN, so it inherits the kit's latency and CSP requirements. A locally defined definition avoids both.
  • Sharp styles are a different geometry set, not a rendering option — you cannot turn a rounded Solid icon into a Sharp one with CSS.
/* Registering the properties makes them interpolate rather than snap. */
@property --fa-secondary-opacity {
  syntax: "<number>";
  inherits: true;
  initial-value: 0.4;
}

@property --fa-primary-opacity {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

/* Now a hover transition on the layer opacity is smooth. */
.duotone-hover {
  --fa-secondary-opacity: 0.35;
  transition: --fa-secondary-opacity 250ms ease-out;
}
.duotone-hover:hover { --fa-secondary-opacity: 1; }

Choosing between free, Pro and Pro+

NeedFreeProPro+
Solid iconsAbout 2,000All SolidAll Solid
BrandsYesYesYes
DuotoneNoYesYes
Sharp stylesNoYesYes
Sharp Duotone, Thumb IconsNoNoYes
Icon Wizard modifiersNoLimitedYes
Custom icon uploadsA small numberMoreMost
Self-hosting the Pro fontsNot applicableYour licence permits it in your projectSame
A private-use code range for your own iconsYesYesYes
// Self-hosting a Pro package: the same pattern as the free one, using the
// packages your licence grants.
// npm install @fortawesome/pro-solid-svg-icons @fortawesome/pro-duotone-svg-icons

import { library } from '@fortawesome/fontawesome-svg-core';
import { faHouse } from '@fortawesome/pro-solid-svg-icons';
import { faHouse as faHouseDuotone } from '@fortawesome/pro-duotone-svg-icons';

// The same iconName in two styles is resolved by the prefix, so both can be
// registered and selected per use.
library.add(faHouse, faHouseDuotone);

// <FontAwesomeIcon icon={['fad', 'house']} />   duotone
// <FontAwesomeIcon icon={['fas', 'house']} />   solid

// Practical advice: do not upgrade a plan for a handful of icons. Define the
// missing ones as custom definitions and keep the free package. Upgrade when
// the design system genuinely depends on the duotone style across hundreds
// of icons.

One licensing point that catches teams out: the Pro icon sets are licensed per developer seat, and the terms restrict redistribution of the raw icon files. Self-hosting inside your own application's build is permitted; publishing the font files as a public asset or bundling them into an open-source template is not. Check the current terms before shipping.

FAQ

How do I make a custom icon appear in both Solid and Duotone?
Define two IconDefinitions with the same iconName and different prefixes — fas and fad — and register both. A duotone definition's path entry is an object with primary and secondary path strings rather than a single string.
Why is my duotone icon only one colour?
Most often the secondary opacity is zero, or both custom properties were set to the same value. Another cause is using the web-font route without Pro, where duotone needs special handling — check that the element actually has the fa-duotone class and the duotone family is loaded.

Transforms, layering, masking and lists Upgrading from Font Awesome 5 and 6 to 7

Last refreshed 2026-09-18.