UI libraries

How to choose an icon set: four measurements

Coverage, grid, weight and licence: four measurements to choose an icon set on the product, not the preview, plus counts for five catalogue families.

Key points

  • A set is chosen with four measurements: coverage, grid, weight and licence; the preview is not one of them.
  • Coverage is counted on the product icons: a family of 324 can cover more than one of 5,166.
  • Stroke and grid are checked at 16px and 24px, where icons actually live.
  • No set covers third-party logos: those carry their own licence and come from a brand kit.

An icon set is chosen with four measurements: coverage, grid, stroke weight and licence. The rest is taste, and taste is not settled in a code review.

The four measurements are taken on the product, not on the preview page. You need the names of the icons you use, the sizes you draw them at, the weight you accept in the bundle and the licence you can honour.

The four measurements

MeasurementQuestionCheck
CoverageDo the icons you need exist?Search the twenty most-used names in the chosen family
GridDoes it hold at the real size?Look at the icons at 16px and 24px, not in the preview
WeightHow much enters the bundle?Measure the named import with the bundle analyzer
LicenceWhat must you keep?Read the package LICENSE file and the project page

1. Coverage: how many icons are actually missing

Coverage is not the total size of the set. It is how many product icons exist in the chosen family, under the name you need. A set of 5,166 icons with three holes in the main commands covers less than a set of 324 that has them all.

The EneUI catalogue indexes 12,808 icons across five SVG families, measured on 1 November 2026: Tabler 5,166, Remix 3,229, Bootstrap Icons 2,078, Lucide 1,853, Heroicons 324. The total comes from `/api/stats` and the per-family counts from the icon index: the two readings can differ by a few units.

2. Grid: the measurement you see at 16px

One family draws on a 24px grid, another on 20px, another on 16px. At 24px the difference disappears; in a 16px toolbar the stroke fades. Before choosing, look at the icons at their real size, not at 64px in the preview.

Stroke and fill

Stroke weight is a system decision, not a per-screen one. If you pick 1.75px, it stays 1.75px in the small icon too. Filled variants mark the active state; they do not change the tone.

3. Weight: what one icon costs

An inline SVG weighs a few hundred bytes; an icon font weighs the whole set. With a modern bundler the named import is dropped when unused, but only if the package exposes separate modules. Check the result in the bundle, not in the documentation.

# quante icone diverse usa il progetto
rg -o "<[A-Z][A-Za-z]+Icon" src | sort -u | wc -l

# griglia e tratto dichiarati negli SVG
rg -o 'viewBox="[^"]+"|stroke-width="[^"]+"' src/icons | sort | uniq -c

# peso del pacchetto prima di installarlo
npm view lucide-react dist.unpackedSize

4. Licence: what you must keep

Tabler is MIT, Lucide is ISC, Remix Icon is Apache 2.0, Bootstrap Icons and Heroicons are MIT. MIT and ISC require the licence text; Apache 2.0 also requires the modification notice. An icon is software: the licence travels with the file.

The ten-minute test

Take the twenty icons your product uses most and look them up in two families. Count the missing ones and the near-matches. If one family covers eighteen out of twenty, you have a choice; if it covers twelve, you have a trade-off to state.

Then look at both families together at 16px and 24px. The family that wins at 16px is the one you will actually use, because that is the size toolbars live at.

The limitation to state

Named limitation: no icon set covers third-party logos. GitHub, Google and client brands carry their own licences and come from a brand kit or a logo catalogue, not from an icon family. Mixing them is correct, because readers recognise them as brands.

The live record is the Tabler search icon; the full browser is at /icons and the Lucide family record at /components/lib/icons-lucide. The comparison between families is in icon coverage 2026, the selection criteria in how to choose a UI library, accessibility in accessible React components and contrast in UI palettes.

Frequently asked questions

How many icons should a set have?

At least every icon the product uses today, plus the ten you will need for the next feature. The catalogue total matters less than coverage of your names.

Outline or filled?

Outline for most of the interface and filled for the active state. Mixing them without a rule makes the set look unfinished.

Can I mix two families?

Yes, but only for brands. Two general icon families use different grids and strokes, and the gap shows at 16px.

Are icon fonts lighter?

No, they usually weigh the whole set. An inline SVG or a tree-shaken named import costs less when you use few icons.

Do SVG icons need an alt attribute?

No, `alt` belongs to images. A decorative SVG uses `aria-hidden`, while one that carries meaning needs an accessible name.