How to Add Custom Icons to Font Awesome 7 Using defineIcons()

To add custom icons to Font Awesome 7, create an icon definition following the internal array format [width, height, ligatures, unicode, svgPath] and register it via library.add() or library.addPack(), which internally invoke defineIcons() to merge icons into the namespace.

Font Awesome 7 exposes a powerful internal utility called defineIcons() that serves as the gateway for extending the library with your own SVG assets. While this function operates behind the scenes in the core runtime, developers can leverage the public library.add() API to register custom icons under unique prefixes, making them available throughout their applications just like standard Font Awesome icons.

How defineIcons() Works Internally

The defineIcons() function is the central registration mechanism in Font Awesome 7's architecture. According to the source code in js/fontawesome.js (lines 1519-1538) and js-packages/@fortawesome/fontawesome-svg-core/index.js (lines 1510-1529), this utility normalizes icon definitions and integrates them into the library's namespace.

When invoked with a prefix and icon set, defineIcons() executes three critical operations:

  1. Normalizes the supplied icons by expanding { icon: [...] } objects into raw arrays
  2. Forwards the normalized data to an addPack hook if present (utilized by the SVG-Core package), or directly merges into namespace.styles[prefix]
  3. Aliases the fas prefix to fa for backward compatibility when fas is explicitly defined

Prerequisites for Custom Icon Definitions

Before registration, your custom icons must conform to Font Awesome's strict internal array format. Each definition requires exactly five elements in this order:

  • width: Integer representing the viewBox width (e.g., 512)
  • height: Integer representing the viewBox height (e.g., 512)
  • ligatures: Array of ligature strings (typically empty [] for custom icons)
  • unicode: String identifier for the unicode private use area (e.g., 'e001')
  • svgPath: String containing the SVG path data commands

Adding Custom Icons with library.add()

Since defineIcons() is not exposed in the public API, use the library.add() method from @fortawesome/fontawesome-svg-core. This method handles the internal call to defineIcons() with proper prefix normalization.

Plain JavaScript (Browser Bundle)

For projects using the global browser distribution:

// Define a custom star icon
const myStar = {
  prefix: 'fac',  // "fac" = Font Awesome Custom
  iconName: 'my-star',
  icon: [512, 512, [], 'e001', 'M256 0 L317 190 H512 L353 308 L384 512 L256 416 L128 512 L159 308 L0 190 H195 Z']
};

// Access the library from the global object
const { library } = window.FontAwesome;

// Register the icon (internally calls defineIcons('fac', { myStar: myStar.icon }))
library.add(myStar);

// Use in HTML
document.body.innerHTML += '<i class="fa-fac fa-my-star"></i>';

ES Modules (Modern Build Systems)

For npm-based projects using a bundler:

import { library, dom } from '@fortawesome/fontawesome-svg-core';

// Define custom rocket icon
const customRocket = {
  prefix: 'fac',
  iconName: 'rocket',
  icon: [
    512,
    512,
    [],
    'e002',
    'M... (SVG path data) ...'
  ]
};

// Register and activate DOM watching
library.add(customRocket);
dom.watch();  // Automatically replaces <i> tags with SVG

Registering Icon Packs with library.addPack()

For bulk registration, use library.addPack(), a thin wrapper around defineIcons() that accepts a prefix and an object mapping icon names to their array definitions:

import { library } from '@fortawesome/fontawesome-svg-core';

// Define multiple icons in a pack
const customPack = {
  'arrow-up': [512, 512, [], 'e003', 'M...'],
  'arrow-down': [512, 512, [], 'e004', 'M...'],
  'home': [512, 512, [], 'e005', 'M...']
};

// Register all icons under the 'fac' prefix via defineIcons()
library.addPack('fac', customPack);

This approach registers the entire pack in a single defineIcons() invocation, optimizing performance for large icon sets.

Key Source Files and Locations

Understanding the underlying implementation helps debug registration issues:

  • js/fontawesome.js (lines 1519-1538): Contains the core defineIcons() implementation for the browser bundle, handling prefix aliasing and direct namespace manipulation.
  • js-packages/@fortawesome/fontawesome-svg-core/index.js (lines 1510-1529): Implements the library.add() and library.addPack() public APIs that sanitize inputs before calling defineIcons().
  • js-packages/@fortawesome/fontawesome-svg-core/plugins.mjs: Manages the addPack hook registration system, allowing the core runtime to delegate icon processing to plugins.

Summary

  • defineIcons() is the internal Font Awesome 7 utility that registers icon sets under specific prefixes (e.g., fas, far, or custom prefixes like fac).
  • Icon definitions must use the standard array format [width, height, ligatures, unicode, svgPath] to pass the normalization checks in the source code.
  • library.add() provides the public API for single icon registration, automatically invoking defineIcons() with proper prefix handling.
  • library.addPack() enables bulk registration of multiple icons under a shared custom prefix, forwarding directly to defineIcons().
  • The implementation resides primarily in js/fontawesome.js and the SVG core package at js-packages/@fortawesome/fontawesome-svg-core/index.js.

Frequently Asked Questions

Is defineIcons() part of the public Font Awesome 7 API?

No, defineIcons() is an internal utility function. The Font Awesome team recommends using library.add() or library.addPack() from @fortawesome/fontawesome-svg-core, which provide a stable public interface while internally delegating to defineIcons() for namespace management.

What is the correct format for custom icon definitions?

Custom icons must follow the five-element array structure: [width, height, ligatures, unicode, svgPath]. For example, [512, 512, [], 'e001', 'M256...'] defines a 512x512 icon with unicode point e001 and the specified SVG path data. This format matches the internal structure used in the official metadata/icons.yml file.

Can I use any prefix for custom icons?

Yes, you can define any custom prefix (commonly fac for "Font Awesome Custom" or your own unique identifier). The defineIcons() function registers these in namespace.styles[your-prefix], making them available via CSS classes like fa-[prefix] fa-[icon-name].

Why does library.add() call defineIcons() instead of directly manipulating the namespace?

This abstraction allows Font Awesome 7 to maintain backward compatibility and support a hook architecture. The addPack hook system enables plugins and framework-specific packages (React, Vue, Angular) to intercept icon registration and apply necessary transformations before the icons enter the global namespace.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →