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
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions