Converting Font Awesome Pro to Iconify JSON
Using the FontAwesome Pro git repository
This example shows how to convert FontAwesome Pro SVG files to Iconify JSON format.
Example assumes you have access to FontAwesome Pro repository. If you do have a valid license, you should have access to it.
Create file convert-fa-pro.ts and put this content:
import { promises as fs } from 'fs';
import {
downloadGitRepo,
importDirectory,
cleanupSVG,
parseColors,
isEmptyColor,
runSVGO,
} from '@iconify/tools';
import type { IconifyInfo } from '@iconify/types';
// Clone repository?
// Set to false if repository is already unpacked to directory set in 'faRepoDir' variable.
const cloneFromGitHub = true;
const faRepoURL: string | null =
'[email protected]:FortAwesome/Font-Awesome-Pro.git';
const faRepoBranch = 'master';
// Directory for FontAwesome Pro repository (automatically downloaded if information above is set)
const faRepoDir = 'fa-pro';
// Themes to parse
const themes = ['brands', 'duotone', 'light', 'regular', 'solid'];
// Directory to export icon sets to
const targetDirectory = 'json';
// Information
const baseInfo: IconifyInfo = {
name: 'Font Awesome',
author: {
name: 'Font Awesome',
},
license: {
title: 'Commercial License',
url: 'https://fontawesome.com/license',
},
height: 32,
};
// Base prefix without theme
const basePrefix = 'fa-pro-';
// Do stuff
(async function () {
// Download repository
let sourceDir = faRepoDir;
if (cloneFromGitHub) {
const downloadResult = await downloadGitRepo({
target: faRepoDir,
remote: faRepoURL,
branch: faRepoBranch,
log: true,
});
sourceDir = downloadResult.contentsDir;
}
// Create directory for output if missing
try {
await fs.mkdir(targetDirectory, {
recursive: true,
});
} catch (err) {
//
}
// Parse all configured themes
for (let i = 0; i < themes.length; i++) {
const theme = themes[i];
const source = sourceDir + '/svgs/' + theme;
const prefix = basePrefix + theme;
// Import icons
const iconSet = await importDirectory(source, {
prefix,
});
// Set info
const info: IconifyInfo = JSON.parse(JSON.stringify(baseInfo));
const themeName = theme.toUpperCase().slice(0, 1) + theme.slice(1);
info.name += ' ' + themeName;
iconSet.info = info;
// Validate, clean up, fix palette and optimise
iconSet.forEachSync((name, type) => {
if (type !== 'icon') {
return;
}
// Get SVG instance for parsing
const svg = iconSet.toSVG(name);
if (!svg) {
// Invalid icon
iconSet.remove(name);
return;
}
// Clean up and optimise icons
try {
// Clean up icon code
cleanupSVG(svg);
// Replace color with currentColor, add if missing
parseColors(svg, {
defaultColor: 'currentColor',
callback: (attr, colorStr, color) => {
return !color || isEmptyColor(color) ? colorStr : 'currentColor';
},
});
// Optimise
runSVGO(svg);
} catch (err) {
// Invalid icon
console.error(`Error parsing ${name}:`, err);
iconSet.remove(name);
return;
}
// Update icon from SVG instance
iconSet.fromSVG(name, svg);
});
console.log(`Imported ${iconSet.count()} icons for ${info.name}`);
// Export to IconifyJSON, convert to string
const output = JSON.stringify(iconSet.export(), null, '\t');
// Save to file
const target = targetDirectory + '/' + prefix + '.json';
await fs.writeFile(target, output, 'utf8');
console.log(`Saved ${target} (${output.length} bytes)`);
}
})().catch((err) => {
console.error(err);
});
Assuming that TypeScript is set to compile to lib, compile file to JavaScript and run it:
node lib/convert-fa-pro
If you are not using TypeScript, remove types from code. It should not be hard because there aren't many lines to remove.
Prepared project is available in Iconify Tools GitHub repository.
Using the FontAwesome Pro npm libraries
An alternative way to generate the JSON files is using the NPM libraries provided by FontAwesome.
Example assumes you have access to FontAwesome Pro npm libraries. See the offficial guide if you don't have access to the libraries yet.
Create file convert-fa-pro-npm.ts and put this content:
import fs from 'fs';
import { blankIconSet } from '@iconify/tools';
import { dirname, join } from 'path';
// import the fonts you want to convert
import {
far as faProRegularIcons,
prefix as faProRegularPrefix,
} from '@fortawesome/pro-regular-svg-icons';
import {
fas as faProSolidIcons,
prefix as faProSolidPrefix,
} from '@fortawesome/pro-solid-svg-icons';
import {
fat as faProThinIcons,
prefix as faProThinPrefix,
} from '@fortawesome/pro-thin-svg-icons';
import {
fal as faProLightIcons,
prefix as faProLightPrefix,
} from '@fortawesome/pro-light-svg-icons';
import type { IconifyInfo } from '@iconify/types';
// put the icons and the prefix you want them to have together in one object.
const icons = [
{ icons: faProRegularIcons, prefix: /* faProRegularPrefix */ 'fa' },
{ icons: faProSolidIcons, prefix: faProSolidPrefix },
{ icons: faProThinIcons, prefix: faProThinPrefix },
{ icons: faProLightIcons, prefix: faProLightPrefix },
] as const;
// set the location where you want the generated json files to appear.
const collectionTargetDir = join(
import.meta.dirname,
'font-awesome-iconify'
);
// set the base info
const baseInfo = {
name: 'Font Awesome',
author: {
name: 'Font Awesome',
},
license: {
title: 'Commercial License',
url: 'https://fontawesome.com/license',
},
height: 512,
} as const satisfies IconifyInfo;
// iterate through the icons and generate the json files
for (const iconData of icons) {
const iconSet = blankIconSet(iconData.prefix);
iconSet.info = structuredClone(baseInfo);
for (const { icon, iconName } of Object.values(iconData.icons)) {
const [width, height, ligatures, unicode, svgPathData] = icon;
// handle strings and array differently from each other
const body =
typeof svgPathData === 'string'
? `<path fill="currentColor" d="${svgPathData}" />`
: `<g fill="currentColor">${svgPathData.map((x) => `<path d="${x}" />`).join('')}</g>`;
iconSet.setIcon(iconName, {
body,
height,
width,
});
ligatures.forEach((x) => {
// ignore the aliases that are numbers.
if (Number.isNaN(+x)) iconSet.setAlias(x, iconName);
});
}
// generate the json
const data = iconSet.export();
const dataJson = JSON.stringify(data, null, 2);
// set the path target for the json file
const jsonTargetDir = join(collectionTargetDir, iconData.prefix);
const fileName = join(jsonTargetDir, 'icons.json');
// create the file
fs.mkdirSync(jsonTargetDir, { recursive: true });
fs.writeFileSync(fileName, dataJson, {
encoding: 'utf-8',
});
}
If you are using NodeJs V22.6.0 or later you can run the TypeScript file natively.
node convert-fa-pro-npm.ts
If your NodeJs version is lower than v23.6.0 you need to add --experimental-strip-types
to the command.
node --experimental-strip-types convert-fa-pro-npm.ts
Alternativly, you can manually remove the types from the code and run it as a JS file instead.