checkpoints.ds

Search the design system

Jump to a page or component

FOUNDATIONS

Iconography

One family, 4,111 glyphs, no exceptions. Mixing icon families is the fastest way to break a pixel aesthetic, so the system allows exactly one — pixelarticons — and types the names so a typo is a compile error.

The library

Four style variants per concept. Base is the outline form; -solid fills it; -sharp and -glyph are denser cuts for small sizes.

TOTAL ICONS
4,111
BASE
1,382

Outline form

SOLID
1,129

Filled variant

SHARP / GLYPH
1,600

Dense cuts

SHOWING 96 OF 4,111

How it renders

The icon is a <span> with the SVG applied as a CSS mask and bg-current for color. No SVG parsing, no per-icon component, no bundle cost that scales with how many icons a page uses — and it inherits text color for free.

TSX
import { PixelIcon } from "@/components/icons/pixel-icon";

// name is typed as PixelIconName — autocomplete covers all
// 4,111 icons. Size via className, color via bg-*.
<PixelIcon name="trophy-solid" className="size-5 bg-action" />

Audit: two renderers ship at once

Both of these are named PixelIcon and both are imported as PixelIcon. Which one a file gets depends entirely on whether the import path says icons/ or ui/.

CANONICAL

apps/web/components/icons/pixel-icon.tsx
Strategy
CSS mask
Coverage
4,111 icons
Imported by
49 files
Unknown name
Compile error

LEGACY

apps/web/components/ui/pixel-icon.tsx
Strategy
Hand-maintained icon map
Coverage
74 icons (2%)
Imported by
12 files
Unknown name
Renders the name as text

WHY IT MATTERS

The legacy component types its name prop as string and falls back to <span>{name}</span>when a lookup misses. A typo doesn't fail the build and doesn't render a missing-icon placeholder — it renders the literal string trophy-solid into the UI, in whatever font that region uses. The canonical component makes the same mistake a type error.

Fix: migrate the 12 remaining importers to @/components/icons/pixel-icon and delete the legacy module. The names differ (PascalCase map keys vs. kebab-case file names), so this is a real migration, not a path rename.