krz-icons logo
Blog

How to Use SVG Icons in React (2025 Guide)

Learn the four main ways to use SVG icons in React apps — inline SVG, React icon components, SVG sprites, and icon fonts — with real code examples and performance tips.


Icons are everywhere in web apps — navigation bars, buttons, empty states, form fields. But the "right" way to use SVG icons in React is not obvious. There are four main approaches, each with real trade-offs.

This guide walks through all of them so you can pick the one that fits your project.

Option 1 — Inline SVG (copy-paste)

The simplest approach: copy an SVG file's markup and paste it directly into your JSX.

export function AlertIcon() {
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      width="24"
      height="24"
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
    >
      <circle cx="12" cy="12" r="10" />
      <line x1="12" y1="8" x2="12" y2="12" />
      <line x1="12" y1="16" x2="12.01" y2="16" />
    </svg>
  );
}

Pros: Zero dependencies. Full control over every attribute. Works with any styling approach.

Cons: Does not scale. Hundreds of icons means hundreds of hand-maintained components. Updating a design system change requires touching every file.

Use it when: You need one or two custom icons that won't change.

Option 2 — React icon component library

A library like krz-icons ships every icon as a ready-made React component. You install the package once and import the icons you need.

import { Bell, Home, Search } from "krz-icons";

export function Navbar() {
  return (
    <nav>
      <Home size={20} />
      <Search size={20} />
      <Bell size={20} />
    </nav>
  );
}

All three props — size, color, and strokeWidth — accept any value and fall back to sane defaults (24, "currentColor", and 1). Any other prop is forwarded to the underlying <svg> element.

Pros: Fast to use. Fully typed (autocomplete in VS Code). Tree-shakeable — only the icons you import end up in your bundle.

Cons: You depend on the library's design decisions. Good libraries like krz-icons are consistent and large (20 000+ icons), but you need to trust the grid and stroke choices.

Use it when: You want a large, consistent set of icons with minimal setup — the common case for production apps.

Option 3 — SVG sprites

A sprite is a single SVG file that holds many icon definitions as <symbol> elements. You reference them with <use> and an href.

// sprite.svg (generated at build time)
<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="home" viewBox="0 0 24 24">...</symbol>
  <symbol id="search" viewBox="0 0 24 24">...</symbol>
</svg>

// Usage
<svg width="20" height="20">
  <use href="/sprite.svg#home" />
</svg>

Pros: One network request for all icons. Browser caches the file. Works in plain HTML without React.

Cons: Harder to control individual icon styles with CSS. Requires a build step to generate the sprite file. Cross-origin <use> references can be blocked by browsers.

Use it when: You have a stable, small icon set and want one cached asset with no JavaScript.

Option 4 — Icon fonts

Icon fonts (like Font Awesome 4) encode each icon as a Unicode character in a custom font file.

<!-- HTML -->
<i class="fa fa-home"></i>

Pros: CSS-only. Every font technique (size, color, shadow) works. Easy to use in non-React apps.

Cons: Bad accessibility by default. Large font files even if you use two icons. Anti-aliasing issues on some screens. Font loading causes FOIT (flash of invisible text).

Use it when: You are in a non-React codebase that already uses icon fonts and changing would be disruptive.

Performance comparison

MethodBundle impactRender costDX
Inline SVGLow (custom only)LowPoor at scale
React componentsLow (tree-shaken)LowExcellent
SVG spriteZero JSVery lowMedium
Icon fontMedium (font file)LowEasy but fragile

Making icons accessible

SVG icons that are purely decorative should be hidden from screen readers. Pass aria-hidden="true" (krz-icons does this automatically) so assistive technology skips them.

When an icon carries meaning — for example a standalone button — pass a title prop or an aria-label on the surrounding button.

<button aria-label="Search">
  <Search size={20} />
</button>

Conclusion

For most React projects, a tree-shakeable component library is the best starting point. You get type safety, a consistent visual language, and instant autocomplete. If you need something beyond a library's catalog, inline SVG is always there as a fallback.

Browse 20 000+ free icons or install krz-icons to get started.


Looking for icons?

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