Skip to content

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:

convert-fa-pro.ts
tsimport { 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:

convert-fa-pro-npm.ts
tsimport 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.

Released under the Apache 2.0 License.