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:
- Normalizes the supplied icons by expanding
{ icon: [...] }objects into raw arrays - Forwards the normalized data to an
addPackhook if present (utilized by the SVG-Core package), or directly merges intonamespace.styles[prefix] - Aliases the
fasprefix tofafor backward compatibility whenfasis 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 coredefineIcons()implementation for the browser bundle, handling prefix aliasing and direct namespace manipulation.js-packages/@fortawesome/fontawesome-svg-core/index.js(lines 1510-1529): Implements thelibrary.add()andlibrary.addPack()public APIs that sanitize inputs before callingdefineIcons().js-packages/@fortawesome/fontawesome-svg-core/plugins.mjs: Manages theaddPackhook 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 likefac).- 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 invokingdefineIcons()with proper prefix handling.library.addPack()enables bulk registration of multiple icons under a shared custom prefix, forwarding directly todefineIcons().- The implementation resides primarily in
js/fontawesome.jsand the SVG core package atjs-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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →