Where Components Win vs Where Sprites Win

  • Framework Components win on ergonomics & per-route isolation: Importing <SettingsIcon /> generated by SVG to JSX gives TypeScript autocomplete, zero external file coordination, and path-level animation props—ideal when each icon appears 1–5 times.
  • Sprites win on high-repetition lists, grids, and tables: Defining <symbol id="star"> once via the SVG Sprite Generator turns 200 rating stars on an e-commerce category page from ~1,000 path nodes into 200 tiny <use href="#star" /> pointers.

The Best of Both Worlds: A Typed React <SpriteIcon> Wrapper

Wrapping <use href> in a union-typed React component for ergonomic sprite consumption
export type CoreIconId = "check" | "chevron-right" | "copy" | "external" | "trash";

interface SpriteIconProps extends React.SVGProps<SVGSVGElement> {
  name: CoreIconId;
}

export function SpriteIcon({ name, className = "size-4 shrink-0", ...props }: SpriteIconProps) {
  return (
    <svg className={className} aria-hidden="true" focusable="false" {...props}>
      <use href={`/sprites/core-ui.svg#icon-${name}`} />
    </svg>
  );
}

With this hybrid pattern, developers keep strict TypeScript autocomplete (<SpriteIcon name="check" />) while the browser caches /sprites/core-ui.svg once across every route.