krz-icons logo
Blog

Building an Icon System for Your Design System

How to choose, standardise, and document icons as part of a design system — grid, stroke, variants, naming, and how to connect your design tokens to icon components.


Icons are one of the most reused elements in a design system. Get them right and every product built on the system looks coherent. Get them wrong and you spend years patching inconsistencies that could have been avoided with a few early decisions.

The grid

Every icon in a system should live on the same grid — typically 24×24, with content inside a safe area of 22×22 (1 px optical margin on each side). The grid sets the rhythm that makes icons look like they belong together.

The most common grid choices:

  • 20×20 — compact, works well at 16–20 px rendered size (common in dense UIs like dashboards).
  • 24×24 — the most popular choice. Works at 16 px (slightly scaled) through 48 px without looking too thin or too heavy. Used by Heroicons, Lucide, and krz-icons.
  • 32×32 — better for larger display icons but harder to use small.

Pick one grid and never mix icons from libraries that use different grids — the visual weight shift is immediately visible to trained eyes.

Stroke

For outline icons, the stroke width determines weight and personality.

  • 1 px — light and minimal, suits clean UI. The krz-icons default.
  • 1.5 px — medium weight, slightly friendlier. The Heroicons default.
  • 2 px — bold, reads well at small sizes and on low-density displays.

Document the baseline. If your system needs multiple weights, pick a library that supports them natively (like Phosphor) rather than mixing libraries.

Naming conventions

Icon names should describe what the icon depicts, not what it means in context. A magnifying glass is always search, even when you use it for "zoom in" or "find". This makes names predictable and avoids the need to update names as usage changes.

Bad (semantic)Good (descriptive)
findsearch
removetrash
navigate-toarrow-right
confirmcheck

For compound names, use hyphens: arrow-up-right, circle-check, bell-off.

Variants

A system with only one variant per icon is limiting. The most useful variants to support:

  • Regular — the base, outline version.
  • Duotone — a filled shape at partial opacity plus the outline. Adds depth for hero sections and empty states.
  • Off — a strikethrough or disabled state (e.g., bell-off, wifi-off). Always use a variant, not just greyed-out color, so colorblind users can tell the difference.
  • Framed — the icon inside a circle, square, hexagon, or octagon. Used for feature icons in marketing sections.

krz-icons ships all four variant families consistently across every icon in the set.

Design tokens for icons

Connect icon size and color to your design token system so icons update when tokens change.

// tokens.ts
export const iconSize = {
  sm: 16,
  md: 20,
  lg: 24,
  xl: 32,
} as const;

// Usage
<Home size={iconSize.md} />

For color, icons inherit currentColor, so connecting them to your token system is as simple as wrapping them in an element with the right text color:

.icon-muted    { color: var(--color-text-subtle); }
.icon-brand    { color: var(--color-brand-500); }
.icon-danger   { color: var(--color-red-500); }

Documentation in Storybook

Document your icon usage in Storybook with a searchable icon gallery. A minimal story for a krz-icons-based system:

// IconGallery.stories.tsx
import * as Icons from "krz-icons";

export const All = () => (
  <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, 120px)", gap: 16 }}>
    {Object.entries(Icons).map(([name, Icon]) =>
      typeof Icon === "function" ? (
        <div key={name} style={{ textAlign: "center" }}>
          <Icon size={24} />
          <p style={{ fontSize: 11, marginTop: 4 }}>{name}</p>
        </div>
      ) : null
    )}
  </div>
);

Checklist

  • Single grid size across all icons.
  • Documented baseline stroke width.
  • Descriptive, not semantic, names.
  • At least regular and off variants.
  • Design tokens for size and color.
  • Searchable documentation (Storybook or similar).

Starting from an existing system saves months of work. Explore krz-icons — it provides the foundation with 20 000+ icons across regular, duotone, off, and framed variants, all on the same 24×24 grid.


Looking for icons?

Browse 20 000+ free, MIT-licensed SVG and React icons.