Node module & API
Add the package to a project:
npm install google-font-cliThe entry point is CommonJS:
const GoogleFontList = require("google-font-cli");There is no separate named export; the module itself is the GoogleFontList constructor.
GoogleFontList
Section titled “GoogleFontList”const fontList = new GoogleFontList();Constructor behavior
Section titled “Constructor behavior”Creating a list starts loading the catalog asynchronously (load(false) is invoked from the constructor). Until loading finishes, fontList.data may still be empty. In your own code, await fontList.load() before searching or reading data. Pass true to force a network fetch and ignore a valid cache (same idea as CLI --refresh-cache).
load returns Promise<{ fromCache: boolean }>. The fromCache flag tells you whether the list came from ~/.gfcli/cache.json.
Properties
Section titled “Properties”| Name | Meaning |
|---|---|
data | Array of GoogleFont instances after the list is populated. |
Loading and data source
Section titled “Loading and data source”| Method | Meaning |
|---|---|
load(forceRefresh?) | Load from cache (if valid and forceRefresh is falsy) or download from https://gwfh.mranftl.com/api/fonts, then populate data. Returns a promise; concurrent calls share the same in-flight promise. |
downloadList() | Download the raw catalog from the network, parse JSON, write cache, populate. Returns Promise<{ fromCache: false }> (or rejects). Used inside load when cache misses. |
populate(fontArray) | Replace data with GoogleFont instances built from an array of plain GWFH-style objects. Emits success. |
Search and filter
Section titled “Search and filter”All of the following use callbacks (err, filteredList) where filteredList is a new GoogleFontList instance whose data is the subset. They read from the current fontList.data, so finish await fontList.load() before calling them.
| Method | Behavior |
|---|---|
searchFont(term, field, callback) | Case-insensitive: every whitespace-separated token in term must appear as a substring of el[field] (e.g. family). Word order does not matter. |
searchFontByName(term, callback) | Same as searchFont(term, 'family', callback). |
searchFontByType(term, callback) | Same as searchFont(term, 'category', callback). |
getFont(term, field, callback) | Exact match of term to el[field] (case-insensitive). |
getFontByName(term, callback) | getFont(term, 'family', callback). |
getFontByType(term, callback) | getFont(term, 'category', callback). |
Helper utilities on a list instance:
| Method | Returns |
|---|---|
getFirst() | First GoogleFont in data, or false if empty. |
isSingle() | true if data.length === 1. |
forEachFont(fn, callback?) | Calls fn(font, index) for each entry; optional callback() when done (synchronous loop). |
clone() | Returns a new GoogleFontList and assigns this list’s data array to it (used for filtered results). |
Events (EventEmitter)
Section titled “Events (EventEmitter)”GoogleFontList inherits Node’s EventEmitter.
| Event | When |
|---|---|
success | Emitted with the list instance when populate runs successfully (including after a downloaded JSON parse). |
error | Emitted when parseRawData cannot parse JSON or the payload is not an array of fonts. |
New code should still await load() rather than relying only on events.
GoogleFont
Section titled “GoogleFont”Each element of fontList.data is an instance of the internal GoogleFont class (constructed from GWFH list entries).
Data on the instance
Section titled “Data on the instance”The constructor **Object.assign**s the raw font record, then sets:
family: fromfamilyNameorfamilycategory,variants: as on the source object (variantsmay be an array of ids or a map)apiUrl:https://gwfh.mranftl.com/api/fonts/{slug}with slug from the family name
Prefer getters below over reading raw fields when you can.
Getters
Section titled “Getters”| Method | Returns |
|---|---|
getFamily() | Family name string. |
getCategory() | Category string or undefined. |
getVariants() | Array of variant ids (keys if variants was an object). |
getCssUrl() | https://fonts.googleapis.com/css?family=... with spaces as +. |
Per-family file map (advanced)
Section titled “Per-family file map (advanced)”| Method | Meaning |
|---|---|
_getFileMapAsync(format) | format: 'ttf' | 'woff2'. Fetches this.apiUrl, parses variant entries, returns Promise<Record<variantId, url>> (only variants that exist for that format). |
_getFileMap(format?, callback?) | Callback or Promise form; see source for overloads. |
Save to disk
Section titled “Save to disk”| Method | Meaning |
|---|---|
saveAtAsync(variants, destFolder, format) | variants: array of ids, or falsy to mean “all keys from the file map”. format: 'ttf' | 'woff2'. Resolves to FontResult[]. If some variants fail to save, throws AggregateError; check err.results for partial FontResult[]. |
saveAt(variants, destFolder, format?, callback?) | Callback style; supports legacy (variants, destFolder, callback) with default format TTF. |
Each FontResult: { family, variant, path }.
Install into the OS (TTF only)
Section titled “Install into the OS (TTF only)”| Method | Meaning |
|---|---|
installAsync(variants) | Downloads TTF only (internal format is fixed to TTF). variants array or falsy for all. Promise<FontResult[]>. |
install(variants, callback) | Callback wrapper around installAsync. |
Variant aliases
Section titled “Variant aliases”Internally, weights are normalized (e.g. 400 / normal → regular, 400italic / normalitalic → italic). Other ids are lowercased and trimmed.
Examples
Section titled “Examples”Async / await (recommended)
Section titled “Async / await (recommended)”const GoogleFontList = require("google-font-cli");
async function main() { const fontList = new GoogleFontList(); await fontList.load();
fontList.searchFontByName("Source Sans Pro", (err, filtered) => { if (err) throw err; const font = filtered.getFirst(); if (!font) return;
font.saveAtAsync(["300", "400"], "./fonts", "ttf").then((results) => { results.forEach((r) => console.log(r.variant, r.path)); }); });}
main().catch(console.error);Promises with getFontByName
Section titled “Promises with getFontByName”const GoogleFontList = require("google-font-cli");
function getFontByNameAsync(list, name) { return new Promise((resolve, reject) => { list.getFontByName(name, (err, filtered) => err ? reject(err) : resolve(filtered) ); });}
(async () => { const fontList = new GoogleFontList(); await fontList.load(); const filtered = await getFontByNameAsync(fontList, "Inter"); if (!filtered.isSingle()) { console.log("Ambiguous or missing"); return; } const inter = filtered.getFirst(); const installed = await inter.installAsync(["regular", "700"]); console.log(installed);})();Events (legacy style)
Section titled “Events (legacy style)”const GoogleFontList = require("google-font-cli");const fontList = new GoogleFontList();
fontList.once("error", (err) => { console.error(err);});
fontList.once("success", () => { fontList.searchFontByName("Roboto", (err, filtered) => { if (err) throw err; filtered.getFirst().install(false, (e, results) => { if (e) throw e; console.log(results); }); });});Note: with load()-driven flows, success may have fired before you attach listeners; await fontList.load() avoids that race.