Skip to content

[RFC]: Remove Icon Fonts in Blueprint v7 (SVG-only icons) #8106

@mm-wang

Description

@mm-wang

Discussed in #8037

Originally posted by ggdouglas April 8, 2026

Status

Summary

This RFC proposes removing Blueprint icon-font support in v7 while preserving:

  • dynamic SVG icon loading (<Icon icon="..." />)
  • static SVG icon components from @blueprintjs/icons

The change removes font-generation tooling, published font artifacts, font-only runtime fallbacks, and icon-font documentation/API surface.

Motivation

Icon fonts are legacy infrastructure with meaningful maintenance overhead:

  • separate build pipeline (Fantasticon + templates + copy scripts)
  • duplicated public APIs (SVG and font paths for the same icons)
  • fallback rendering path in core Icon component
  • large published binary/font artifacts
  • broad CSS codepoint surface in core and docs styles

The v7 direction is to make SVG the only icon rendering mechanism.

Current State (Before This RFC)

Build pipeline (source SVG -> fonts + CSS + SVG paths + static components)

@blueprintjs/icons currently runs:

  1. generate-icon-fonts.mjs (Fantasticon):
    • input: resources/icons/{16px,20px}/*.svg + icons.json
    • output: src/generated/{16px,20px} font files (eot, ttf, svg, woff, woff2)
    • output: generated font CSS + SCSS + TS codepoint files
  2. generate-icon-paths.mjs:
    • output: src/generated/{16px,20px}/paths/*.ts for dynamic SVG icons
  3. generate-icon-components.mjs:
    • historically parsed font-generated SVG glyph output and applied transforms
  4. package build copies/compiles:
    • copy-fonts.sh -> lib/css/*.woff2|...
    • copy-scss.sh -> lib/scss/blueprint-icons-16.scss, blueprint-icons-20.scss, variables.scss
    • compile:css + dist:css -> lib/css/blueprint-icons.css

Consumer usage today

  • CSS font import:
    • @blueprintjs/icons/lib/css/blueprint-icons.css
  • CSS icon classes:
    • bp6-icon-standard / bp6-icon-large + bp6-icon-<name>
  • codepoint helpers:
    • IconCodepoints, getIconContentString

Tech debt and package weight (measured)

The removed @blueprintjs/icons/lib/css artifacts totaled 1,806,719 bytes:

  • 10 font binaries (eot, ttf, svg, woff, woff2) across 16px + 20px
  • blueprint-icons.css + sourcemap

Additional removed font SCSS API files:

  • lib/scss/blueprint-icons-16.scss
  • lib/scss/blueprint-icons-20.scss
  • lib/scss/variables.scss

Prerequisite: PR #8036 Alignment

Before removing icon fonts, static icon generation must no longer depend on font glyph transforms.

PR #8036 introduces this direction by generating static icon components from optimized resource SVG paths (same source of truth as dynamic path modules), preventing clipping/mismatch issues and decoupling static SVG correctness from font generation.

This RFC adopts that approach as a prerequisite.

Proposal

1) Remove icon-font build pipeline from @blueprintjs/icons

  • delete:
    • scripts/generate-icon-fonts.mjs
    • scripts/copy-fonts.sh
    • scripts/copy-scss.sh
    • font templates (icons.css.hbs, icons-16.scss.hbs, icons-20.scss.hbs)
    • font source entrypoint src/blueprint-icons.scss
    • font template API file src/templates/_lib_variables.scss
  • update package.json:
    • remove style entry for lib/css/blueprint-icons.css
    • remove compile:css, copy:*, dist:css
    • generate-icon-src only runs SVG path/component generators
    • remove Fantasticon dependency

2) Keep static + dynamic SVG icons intact

  • generate-icon-paths.mjs and generate-icon-components.mjs extract path data from optimized resource SVG files.
  • add shared helper: scripts/extractPathsFromResourceSvg.mjs.
  • ensure generated path exports and generated components use serialized path strings safely.

3) Remove font-only runtime and API surface

  • remove Icon font fallback path in core:
    • if SVG paths are unavailable, do not render fallback font glyph classes
  • remove exported font codepoint API in icons package:
    • IconCodepoints
    • getIconContentString

4) Remove icon-font docs and internal imports

  • remove docs references to:
    • @blueprintjs/icons/lib/css/blueprint-icons.css
    • @blueprintjs/icons/lib/scss/variables
    • codepoint-based examples
  • update app/docs styles that imported icon-font CSS or depended on codepoint maps.

5) Remove core CSS codepoint generation coupling

  • remove @blueprintjs/icons/lib/scss/variables coupling from core/docs/datetime SCSS.
  • remove .bp6-icon-*:before codepoint rule generation path from core icon styles.

Implementation Notes (Experimental Branch)

Implemented in branch:

  • static/dynamic generation decoupled from font glyph transforms
  • font build/copy scripts and font templates removed
  • font public exports removed from @blueprintjs/icons
  • core icon font fallback removed
  • docs and package stylesheet imports updated to remove icon-font CSS dependency

Verification Performed

  • pnpm --filter @blueprintjs/icons generate-icon-src
  • pnpm --filter @blueprintjs/icons compile
  • pnpm nx compile @blueprintjs/core
  • pnpm nx compile @blueprintjs/datetime
  • pnpm nx compile @blueprintjs/docs-theme

All commands completed successfully in this branch.

Expected Impact

Size and distribution

  • remove ~1.8 MB raw icon-font payload from @blueprintjs/icons/lib/css publish artifacts
  • remove icon-font SCSS variable distribution files
  • remove icon-font dependency chain from build tooling

API and behavior changes

Breaking (v7):

  • no icon font CSS entrypoint (@blueprintjs/icons/lib/css/blueprint-icons.css)
  • no icon-font class rendering path for icons
  • no codepoint helper exports (IconCodepoints, getIconContentString)

Non-breaking intent for SVG users:

  • dynamic <Icon icon="..."> SVG behavior remains supported
  • static icon components remain supported

Migration Guide (for consumers)

If currently using icon fonts:

  1. Remove icon-font stylesheet imports.
  2. Replace font-class markup (bp6-icon-*) with SVG icon rendering:
    • use Blueprint component icon props
    • or static icon React components from @blueprintjs/icons
  3. Replace codepoint pseudo-element usage with:
    • inline SVG/icon components
    • or explicit textual symbols where appropriate for non-icon UI marks

Risks

  • downstream consumers relying on CSS icon classes will break in v7
  • consumers relying on codepoint helpers in pseudo-elements will need migration
  • docs/examples that historically used codepoint maps require explicit updates

Alternatives Considered

  • phased deprecation with temporary compatibility shim:
    • lower immediate breakage but prolongs dual-system maintenance
  • hard removal in v7 (this RFC):
    • clearer API direction and immediate maintenance reduction

Open Questions

  • should a codemod be provided for common class-based icon usage patterns?
  • should we add temporary runtime warnings in v6.x before v7 removal?
  • do we want a focused migration guide page linked from v7 release notes?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions