Features
Capabilities webfont provides — stability status, behavior details, and test-backed criteria for each feature. Test criteria use ✅ when coverage exists; ⬜ when not yet covered.
SVG icon font generation
- Stability: stable
- Description: Build a font from one or more
.svgicon files (icon font / webfont workflow). - Properties:
- Input: globs resolving to
.svgfiles only (every matched file must have a.svgextension). - Uses svgicons2svgfont to merge icons into an SVG font, then derives other formats from that TTF pipeline.
- Does not accept
.woff,.woff2,.ttf, or.otfas input in the same run. - Licensing: you must have rights to the SVG icons you submit; generated fonts remain subject to those rights and any metadata you set. See NOTICE.md §3.1.
- Input: globs resolving to
- Test Criteria:
- ✅ SVG glob produces
svg,ttf,eot,woff, andwoff2with defaultformats - ✅ Empty or unsupported globs reject with a clear error
- ✅ Mixed
.svg+.woff/.woff2inputs reject
- ✅ SVG glob produces
SVG pipeline output formats
- Stability: stable
- Description: Emit subset of
svg,ttf,eot,woff,woff2from SVG icon input. - Properties:
- Default
formats:['svg', 'ttf', 'eot', 'woff', 'woff2']. otfis not supported for SVG input (the pipeline produces TrueType outlines viasvg2ttf).- Requesting
otfwith SVG input fails early with an explicit error (no silent success, no emptyotfbuffer). eot,woff, andwoff2are generated from the intermediate TTF buffer.
- Default
- Test Criteria:
- ✅
--formats/formatsoption limits written outputs - ✅ SVG input with
formats: ['otf']rejects - ✅ Built-in CSS template works with default SVG formats
- ✅
TTF to webfont encoding
- Stability: in-progress
- Description: Encode one or more
.ttfTrueType files tosvg,eot,woff, and/orwoff2(and optional TTF pass-through). Auto-detected from input extension — no separate flag (see #13). - Properties:
- Input: one or more local
.ttfpaths or globs per run. - Output:
ttf(copy),svg(SVG font),eot,woff, and/orwoff2per input via existing encoders (fonteditor-core,ttf2eot,ttf2woff,wawoff2). svgproduces a legacy SVG font (glyph outlines + metrics as XML) viafonteditor-core— pure JS, no Java/FontForge (#764). Opt-in only; not part of the default output set.- Batch results on
result.transcodedFonts({ source, svg?, ttf?, eot?, woff?, woff2? }[]). Single input mirrors buffers onresulttop level (result.svgis a string). - Default
formatswhen SVG-pipeline defaults are still configured:['woff', 'woff2'](SVG font stays opt-in). - Does not accept
.otfinput (TrueType only). Does not merge multiple weights into one file. templateandglyphTransformFnare not supported in this mode.glyphContentTransformFnis not supported in this mode.- Licensing: encoding does not grant rights to the font; users must comply with the font’s license. See NOTICE.md §3.3.
- Architecture: see ADR 0009.
- Input: one or more local
- Test Criteria:
- ✅
.ttfinput withformats: ['woff', 'woff2']yields valid WOFF and WOFF2 - ✅
.ttfinput withformats: ['svg']yields a valid SVG font (#764) - ✅ Default formats produce
woff+woff2when SVG defaults are configured (no SVG font) - ✅ Multiple TTF files encode in one run (
transcodedFonts), includingsvg - ✅ Mixed
.svg+.ttfor.ttf+.woff2inputs reject - ✅ Template option in TTF mode rejects
- ✅ CLI writes encoded outputs (incl.
svg) for a single TTF input
- ✅
WOFF / WOFF2 container decompression
- Stability: in-progress
- Description: Decompress one or more
.woff/.woff2inputs (local paths, globs, orhttp(s)URLs) to the SFNT payload inside each file (TTF or OTF), not arbitrary format transcoding or font merging. - Properties:
- Input: one or more
.woff/.woff2sources per run (paths, globs, and/or URLs). - Output:
ttfand/orotfper input — whichever matches each decompressed SFNT flavor (0x00010000/true→ TTF,OTTO→ OTF). - Batch results are exposed on
result.decompressedFonts({ source, ttf?, otf? }[]). A single input still setsresult.ttf/result.otfat the top level for backward compatibility. - CLI writes
{basename}.ttf/.otfper input; colliding basenames (e.g.iconfont.woff+iconfont.woff2) use-woff/-woff2suffixes. A single input still honors-u/fontName. - URLs must end in
.woffor.woff2(query strings allowed). Response must be a valid WOFF/WOFF2 container. - Does not merge multiple weights into one SFNT file (see NOTICE.md).
- Does not convert TrueType outlines to PostScript/CFF (TTF → OTF) or the reverse; use an external tool (e.g. FontForge) for that.
- Does not re-encode to
eot,woff, orwoff2in this mode. - Default
formatswhen SVG-pipeline defaults are still configured:['ttf']. templateandglyphTransformFnare not supported in this mode.glyphContentTransformFnis not supported in this mode.- Licensing: decompression does not grant rights to the font; users must comply with the font’s license for input and extracted output. Copyright/metadata in the SFNT is preserved. See NOTICE.md §3.4.
- Architecture: see ADR 0007.
- Input: one or more
- Test Criteria:
- ✅
.woff2input withformats: ['ttf']yields a valid TTF when the container holds TrueType - ✅
.woffinput withformats: ['ttf']yields a valid TTF when the container holds TrueType - ✅ Multiple webfont files decompress in one run (
decompressedFonts) - ✅ HTTPS URL input decompresses when fetch returns a valid WOFF2
- ✅ Requesting
ttfwhen the SFNT flavor is OTF rejects with a flavor hint - ✅ Requesting
otfwhen the SFNT flavor is TTF rejects with a flavor hint - ✅ Template option in webfont conversion mode rejects
- ✅
Supported input file classification
- Stability: in-progress
- Description: Classify matched paths into SVG mode, webfont mode, mixed, or unsupported before running a pipeline.
- Properties:
- Supported extensions:
.svg,.ttf,.woff,.woff2only. - Extension-less paths (e.g.
LICENSE,.webfontrc) are not treated as compatible wildcards; globs that match them alongside fonts fail as unsupported. - Unsupported extensions (e.g.
.txt,.json) cause the run to fail with “did not match any supported files”.
- Supported extensions:
- Test Criteria:
- ✅ Extension-less file +
.woff2classifies as unsupported (error) - ✅
.txt-only input classifies as unsupported (error) - ✅ Pure
.svg/ pure.ttf/ pure.woff/.woff2classify correctly
- ✅ Extension-less file +
Configuration file discovery
- Stability: stable
- Description: Load options from cosmiconfig (
package.jsonwebfontkey,.webfontrc,webfont.config.js, etc.). - Properties:
- Search walks up from cwd when no explicit
configFile/--configis set. - Discovered path is exposed on
result.config.filePath(output metadata only).
- Search walks up from cwd when no explicit
- Test Criteria:
- ✅ Custom config
formatsare respected - ✅ Discovered
filePathattached on conversion runs
- ✅ Custom config
CSS / SCSS / Styl templates
- Stability: stable
- Description: Generate
@font-face(or equivalent) from built-in or custom Nunjucks templates. - Properties:
- Built-in:
css,scss,styl. - Custom template: path to a Nunjucks file.
- SVG pipeline only (not webfont decompression or TTF encoding mode).
templateCacheString: manual query string on font URLs (defaultDate.now()).addHashInFontUrl: append MD5&v=<hash>from SVG font content; filenames stayfontName.*(#125).unicodeRange: opt-inunicode-rangein built-in@font-facefrom glyph code points (default off);unicodeRange: true,--unicode-range, or a CSS string to enable (#322). Enabling may break ligature-by-name usage — see README / TROUBLESHOOTING.
- Built-in:
- Test Criteria:
- ✅ Built-in
csstemplate snapshot / integration coverage - ✅ Subset
formatswith template omits unused format URLs - ✅
addHashInFontUrloncssandscsstemplates appends content hash to URLs - ✅
unicodeRange: true/--unicode-rangeadds computedU+<min>-<max>to built-in templates; default omits it - ✅
templateFontNamesets CSSfont-family(fontFamily);fontNamestays on output file URLs (#331)
- ✅ Built-in
Command-line interface (CLI)
- Stability: stable
- Description: Run
webfontfrom the shell viadist/cli.mjs(npmbin). - Properties:
- Parses
--formatsas JSON array or comma-separated list. - Writes font files to
--dest; optional template output. - Errors and verbose stacks go to stdout; stderr must stay empty (see integration tests).
- Exit code
0on success,1on handled errors.
- Parses
- Test Criteria:
- ✅ CLI integration tests cover success, failure, and
--verbose - ✅
parseFormatsFlagvalidates format names includingotf - ✅
validateWebfontOptionsrejects unknownformatsfrom API and cosmiconfig (#133)
- ✅ CLI integration tests cover success, failure, and
Option validation
- Stability: stable
- Description: Reject mis-typed options before running the pipeline.
- Properties:
formatsmust be a non-empty array of known format names (svg,ttf,otf,eot,woff,woff2).files,fontName,template, andtemplateFontPathtype-checked after cosmiconfig merge.
- Test Criteria:
- ✅ Unit tests in
validateWebfontOptions.test.ts - ✅ Standalone and CLI integration tests for unknown format names (#133)
- ✅ Unit tests in
Multiple templates
- Stability: stable
- Description: Generate more than one style/preview template per run.
- Properties:
templateaccepts a string or array of built-in names (css,html,scss,styl,json) or custom template paths.result.templateslists each rendered output;result.templateremains the first entry for backward compatibility.- Built-in
htmlpreview:templateFontLigatures(default on) addsfont-feature-settings: "liga"for the Ligature section; ifunicodeRangeis also enabled, HTML omits PUA-onlyunicode-rangeon@font-faceso ASCII ligature names use the icon font. ligaturesdefault off (performance on large fonts, #558); opt in with--ligatures; runtime warning when >2k glyphs with ligatures enabled.
- Test Criteria:
- ✅ Standalone and CLI tests for
template: ['html', 'scss'](#158) - ✅ HTML template enables
ligaCSS by default; omitsunicode-rangewhen both ligature preview andunicodeRangeare enabled - ✅ Large-font ligature warning unit tests (#558)
- ✅ Standalone and CLI tests for
Glyph metadata hooks
- Stability: stable
- Description: Customize per-glyph metadata in the SVG pipeline.
- Properties:
metadataProvider: replace default SVG metadata lookup.glyphTransformFn: transform metadata after load (SVG mode only).glyphContentTransformFn: transform SVG glyph contents before font generation (SVG mode only; e.g. stroke-to-fill viasvg-outline-stroke, #144).optimizeSvg: optional conservative SVGO pass beforeglyphContentTransformFn(default off; #724). Does not fix stroke-only SVGs alone (#327).svgoConfig: optional SVGOConfigwhenoptimizeSvgis enabled.
- Test Criteria:
- ✅
glyphTransformFnapplied before font generation - ✅
glyphContentTransformFnapplied before font generation (#144) - ✅
metadataProvidererror paths unit-tested (glyphsData) - ✅
optimizeSvgstrips comments/metadata without breaking default fixtures (#724) - ✅ Empty SVG font glyph paths reject with guidance (#327)
- ✅
TTF output hook (ttfPostProcess)
- Stability: stable
- Description: Caller-owned post-processing of the generated TTF buffer, before WOFF/WOFF2/EOT are derived from it (SVG pipeline only). Keeps optional/native steps (e.g. autohinting via
ttfautohint) out of the core — same philosophy asglyphContentTransformFn(ADR 0011); enabling package for #749. SeettfPostProcessin the configuration reference. - Properties:
- Signature
(ttf, { fontName, formats }) => Buffer | Uint8Array | Promise<…>. - Runs once, after
toTtf; all derived formats come from the returned buffer. - webfont bundles no hinting/native dependency; the hook is opt-in.
- Signature
- Test Criteria:
- ✅ Called with the generated TTF and context; return value used as
result.ttf - ✅ Derived
woff2produced from the post-processed TTF - ✅ Async hook supported
- ✅ Called with the generated TTF and context; return value used as
svgicons2svgfont options
- Stability: stable
- Description: Pass font metrics and layout options through to svgicons2svgfont (normalize, fixed width, ascent/descent, etc.).
- Properties:
- Documented in Configuration.
- SVG pipeline only.
- Test Criteria:
- ✅ Options forwarded via
getFontStreamOptions/ standalone integration tests
- ✅ Options forwarded via
SVG tools — diagnostics (alpha)
- Stability: alpha
- Description: Scan SVG icon sources for icon-font incompatibilities before font generation. Stroke-to-fill and other SVG repairs are out of scope — use
glyphContentTransformFn(see ADR 0011). - Properties:
svgTools.diagnose: warn aboutfill-rule: evenodd, stroke-only paths,<use>references (#612), and unsupported SVG elements; populateresult.svgDiagnostics.- CLI flag:
--svg-diagnose(alpha). --verbosestill logs evenodd warnings for backward compatibility.- Programmatic helpers:
diagnoseSvgContents,diagnoseGlyphsDataexported from the package entry.
- Test Criteria:
- ✅ Unit tests for stroke/evenodd/element detection
- ✅
glyphContentTransformFnapplied before font generation (#144) - ✅ CLI integration tests for
--svg-diagnose
Arbitrary format transcoding
- Stability: planned
- Description: Convert between outline/container formats beyond the current three pipelines (e.g. TTF ↔ OTF transcoding, OTF input encoding).
- Properties:
- Partially supported: TTF →
svg(SVG font) /eot/woff/woff2(see TTF to webfont encoding). WOFF/WOFF2 → TTF/OTF decompression. - Out of scope today: OTF input encoding, TTF ↔ OTF outline conversion.
- External tools (FontForge, fontTools, etc.) are required for TTF → OTF today.
- Partially supported: TTF →
- Test Criteria:
- ✅ TTF input encoded to WOFF/WOFF2
- ⬜ TTF input transcoded to OTF
- ⬜ Documented public API for generic transcoding
Are you a contributor?
This file is the canonical capability list. Update it in the same PR whenever behavior, supported inputs/outputs, or public options change. See CONTRIBUTING.md for the full documentation checklist.