Skip to content

perf(react-icons): reuse canonical fonts instead of regenerating#1105

Merged
Hotell merged 3 commits into
microsoft:mainfrom
Hotell:react-icons/reuse-canonical-fonts
Jun 30, 2026
Merged

perf(react-icons): reuse canonical fonts instead of regenerating#1105
Hotell merged 3 commits into
microsoft:mainfrom
Hotell:react-icons/reuse-canonical-fonts

Conversation

@Hotell

@Hotell Hotell commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

The react-icons build re-ran fantasticon (~48s/variant) to generate font families that already exist in the repo-root fonts/ folder — the single source of truth, regenerated at release time by importer's deploy:fonts. This PR removes that redundant work: react-icons now just copies the canonical fonts.

Changes

1. Deterministic font generation — importer/generateFont.js

  • formatOptions.ttf.ts = 0 pins svg2ttf's created/modified timestamps so font binaries are byte-deterministic across builds (WOFF/WOFF2 wrap the TTF bytes). This was the root cause of font binary churn between builds.
  • Sort glob results so codepoint assignment is stable regardless of filesystem readdir order.

2. Stable cross-release codepoints — importer/package.json

  • Seed Light & Resizable codepoints from the committed root fonts/ JSON. Previously they were unseeded and could drift on every build; now all four families are seeded.

3. react-icons copies instead of regenerating

  • New scripts/copy-base-fonts.js copies the font binaries + glyph-named codepoint JSON from root fonts/ (skips the unused .css/.html fantasticon byproducts).
  • generate:font is now that single copy step — the four generateFont.js (fantasticon) invocations are removed from the react-icons build.
  • Removed the now-unused concurrently devDependency.

4. nx caching

  • Added a cacheable deploy:fonts target (importer/project.json) keyed on assets/** + the generation scripts, output {workspaceRoot}/fonts.
  • react-icons build cache inputs now include the root fonts/ artifacts, so it invalidates when fonts change.
  • Renamed the nx project @fluentui/system-icons-processingsystem-icons-processing (npm package name unchanged).

5. DRY cache inputs via composable named inputs

  • Replaced duplicated/inlined input globs with composable namedInputs in nx.json, each defined once:
    • assetsassets/**
    • iconGenerationToolchain — shared importer/generate.js, replace-in-files.js, svgo.config.shared.cjs
    • fontGenerationToolchain — composes iconGenerationToolchain + generateFont.js, svgo.config.mjs, package.json
    • fontArtifactsfonts/FluentSystemIcons-*.{ttf,woff,woff2,json}
  • importer (deploy:fonts), svg-icons (build), and react-icons (build) now reference these instead of inlining the same globs.
  • Fixed a dangling implicitDependency in svg-icons (@fluentui/system-icons-processingsystem-icons-processing) surfaced by the rename.

Behavior note (Option A: pure copy)

Brand-new icons added between releases won't have font glyphs in react-icons until a release runs deploy:fonts (which precedes the react build in publish.yml). Published output stays correct.

Verification

  • Full react-icons:build ✅ (no fantasticon runs)
  • build-verify 127 tests ✅, convert-font.utils 8 tests ✅ — no snapshot changes needed
  • react-icons lib/utils/fonts/* is now byte-identical to root fonts/ (expected one-time shift from raw → optimized geometry; functionally identical glyphs/codepoints)
  • Two consecutive generateFont.js runs now produce byte-identical ttf/woff/woff2
  • nx project graph resolves cleanly (no dangling refs); svg-icons:build produces a cache hit on re-run

Follow-up (not in this PR)

Regenerating the committed root fonts/ with the new deterministic bytes (deploy:fonts) is left as a separate, reviewable commit.

@Hotell Hotell force-pushed the react-icons/reuse-canonical-fonts branch from 9e4c6d3 to 439bd37 Compare June 15, 2026 13:36
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

📋 PR Validation Summary

Check the Build react library job summary for detailed reports:

  • 📦 Bundle Size — size comparison against the base branch
  • 📖 Docsite Preview — build artifact with local preview instructions

To view: click the link above → select the Build react library job → open the Summary tab.

@Hotell Hotell force-pushed the react-icons/reuse-canonical-fonts branch 2 times, most recently from 68cc82f to 2103cf3 Compare June 16, 2026 10:31
@Hotell Hotell marked this pull request as ready for review June 16, 2026 12:05
@Hotell Hotell requested review from a team as code owners June 16, 2026 12:05
@tudorpopams tudorpopams requested a review from dmytrokirpa June 16, 2026 12:12
@Hotell Hotell requested a review from mainframev June 29, 2026 16:05
Hotell added 3 commits June 30, 2026 11:16
react-icons previously re-ran fantasticon 4x (~48s/variant) to build font
families that already exist in the repo-root fonts/ source of truth. Replace
that with a copy step.

- importer/generateFont.js: make font output byte-deterministic
  (ttf.ts=0 pins svg2ttf timestamps; sort glob for stable codepoints)
- importer/package.json: seed Light/Resizable codepoints from root fonts/
  so they stay stable across releases (previously unseeded -> drifted)
- react-icons: replace generate:font-* (fantasticon) with copy-base-fonts.js
  that copies binaries + glyph-named JSON from root fonts/; drop unused
  concurrently dep
- nx: add cacheable deploy:fonts target (importer/project.json) keyed on
  assets/ via new "fonts" namedInput; react-icons build invalidates on
  root fonts/ changes
- rename nx project @fluentui/system-icons-processing -> system-icons-processing
Deduplicate input cache configuration shared across the font/svg generation
targets.

- nx.json: replace the monolithic "fonts" namedInput with composable
  "assets", "iconGenerationToolchain", "fontGenerationToolchain"
  (composes the former), and "fontArtifacts"
- importer (deploy:fonts): inputs -> ["assets", "fontGenerationToolchain"]
- svg-icons (build): reuse ["assets", "iconGenerationToolchain"] instead of
  inlining assets/** + importer scripts; also fix dangling implicitDependency
  @fluentui/system-icons-processing -> system-icons-processing
- react-icons (build): replace the 4 inlined fonts/* globs with "fontArtifacts"
@Hotell Hotell force-pushed the react-icons/reuse-canonical-fonts branch from 8bad1a5 to 5c00fac Compare June 30, 2026 09:16
@Hotell Hotell merged commit d765cea into microsoft:main Jun 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants