Skip to content

Install webfont ​

Generate icon fonts from SVG files at build time with the webfont CLI or the Node.js webfont() API. This guide covers install, wiring, optional config, and a first successful run.

Requirements ​

  • Node.js >= 24.14.0 (engines in package.json; CI tests Node 24.x and 26.x)
  • Build-time only — use npm scripts, the CLI, or Node build hooks. Do not import webfont from browser or React client bundles (troubleshooting).

Check your Node version:

shell
node --version

Install ​

From your project root:

shell
npm install --save-dev webfont

Homebrew (macOS / Linux CLI) ​

Recommended — homebrew-core (no tap):

shell
brew install webfont

If Homebrew reports that no formula named webfont exists, refresh the index first:

shell
brew update
brew install webfont

Homebrew installs the published npm tarball and requires the node formula. Verify the CLI:

shell
webfont --version

Monorepo tap (optional) — use when you want the webfonts alias or a formula change before it lands in core (#769):

shell
brew tap itgalaxy/webfont https://github.com/itgalaxy/webfont
brew install webfont

The alias webfonts works only in the tap:

shell
brew install webfonts

Switching from tap to core — if you already installed from itgalaxy/webfont and want the core formula:

shell
brew uninstall webfont
brew untap itgalaxy/webfont
brew update
brew install webfont

For library use inside a Node project, prefer the npm dev dependency above.

Grunt (legacy projects) ​

grunt-webfont is archived. Use a custom Grunt task that calls webfont() and writeResultFiles() — see Grunt integration (#771, ADR 0014).

Verify ​

CLI (npm project)

shell
npx webfont --version

CLI (Homebrew)

shell
webfont --version

Programmatic API — prefer the named export:

shell
node --input-type=module -e "import { webfont } from 'webfont'; console.log(typeof webfont)"

Expected: function. CommonJS also works: const { webfont } = require("webfont").

On webfont 12.x+, default ESM import is callable too; { webfont } remains the recommended form for new code.

Use the CLI ​

Add a script to package.json:

json
{
  "scripts": {
    "webfont": "node node_modules/webfont/dist/cli.mjs"
  }
}

On Windows-heavy teams, cross-env avoids path issues:

json
{
  "scripts": {
    "webfont": "cross-env node_modules/webfont/dist/cli.mjs"
  }
}

Run with npm run webfont -- <flags> (-- forwards arguments to the CLI).

All flags: CLI reference · source

Interactive assistant ​

For a guided flow (same idea as webfont-assistant):

shell
webfont --assistant

Rerun from a saved .was config:

shell
webfont --assistant-config assets/fonts/MyAwesomeFont.was

--assistant-config is not the same as --config (cosmiconfig).

Use the programmatic API ​

js
import { webfont } from "webfont";

const result = await webfont({
  files: "src/icons/**/*.svg",
  fontName: "my-icons",
  formats: ["woff2"],
});

// result.woff2, result.ttf, result.template, …

Full options: Configuration · docs site

Configuration files ​

Store defaults in cosmiconfig instead of repeating flags every run. When no explicit path is given, webfont searches upward from the working directory:

  1. webfont key in package.json
  2. .webfontrc (.json, .yaml, or .js)
  3. webfont.config.js

package.json

json
{
  "webfont": {
    "files": "src/icons/**/*.svg",
    "fontName": "my-icons",
    "formats": ["woff2"],
    "template": "css",
    "dest": "dist/fonts"
  }
}

webfont.config.js

js
export default {
  files: "src/icons/**/*.svg",
  fontName: "my-icons",
  formats: ["woff2"],
  template: "css",
  dest: "dist/fonts",
};

Point to a specific file with CLI --config or API configFile. After a run, result.config.filePath shows which file was loaded (output metadata only — do not set this in config).

First run ​

Put at least one .svg in icons/ (e.g. icons/star.svg).

CLI

shell
npm run webfont -- "./icons/*.svg" -d dist/fonts -f woff2 -t css -u my-icons --dest-create

API — write buffers yourself (the API does not write to disk unless you use the CLI flow):

js
import { mkdir, writeFile } from "node:fs/promises";
import path from "node:path";
import { webfont } from "webfont";

const dest = "dist/fonts";
await mkdir(dest, { recursive: true });

const result = await webfont({
  files: "icons/*.svg",
  fontName: "my-icons",
  formats: ["woff2"],
  template: "css",
});

await writeFile(path.join(dest, "my-icons.woff2"), result.woff2);
if (result.template) {
  await writeFile(path.join(dest, "my-icons.css"), result.template);
}

Confirm output:

shell
ls dist/fonts/

You should see my-icons.woff2 and, with -t css, my-icons.css.

Tips ​

  • Pipelines are mutually exclusive per run: .svg (icon font), .ttf (encode), or .woff/.woff2 (decompress). See Capabilities at a glance.
  • Font rights: you must be allowed to process every input file. See NOTICE.md.
  • Webpack: prefer the webpack plugin or call webfont from a Node build script, not from client bundles.
  • Grunt: see Grunt integration (replacement for archived grunt-webfont).

This file lives at packages/webfont/install.md in the monorepo and ships on npm as webfont/install.md for tooling such as install.md.