Loading...

How to Use SVG Icons in React

September 3, 2026

How to Use SVG Icons in React

Look, we’ve all been there. You’re building out a new React component, you need a quick "close" or "search" icon, and you grab an SVG from Figma, Iconify, or somewhere else on the web.

You open the file, and it’s a massive wall of XML code. Now you’re staring at your JSX, wondering: Do I just paste this in? Is there a better way? How do I even change the color of this thing?

If you've ever felt that headache, you're in the right place. Figuring out how to use SVG icons in React doesn't have to be a guessing game. There are a few different ways to handle them, and the "best" way really depends on what you're trying to build.

Let’s break down the most common methods, from the quick-and-dirty to the absolute best practices, so you can stop wrestling with SVG code and get back to building your app.


Why Bother with SVGs Anyway?

Before we get into the code, let’s quickly remind ourselves why we use SVGs in the first place. Unlike PNGs or JPEGs, SVGs are vector-based. That means they scale perfectly to any screen size without getting pixelated. They also have tiny file sizes, and because they are essentially code, you can manipulate them directly with CSS and JavaScript.

In React, this flexibility is a superpower—if you implement them correctly.

Method 1: The "React Way" (Importing as a Component)

Best for: Custom icons, design system components, and when you need to change colors dynamically.

If you ask most senior React developers how they handle custom SVGs, this is the answer they’ll give you. Instead of treating an SVG like an image file, you treat it like a React component.

Modern build tools like Vite and Create React App (CRA) make this incredibly easy.

How to do it in Vite (The Modern Standard)

If you’re using Vite, you just need to append ?react to your import statement.

import React from 'react';
// Notice the ?react at the end
import StarIcon from './assets/star.svg?react'; 

function FavoriteButton() {
  return (
    <button>
      {/* You can pass props just like a normal component! */}
      <StarIcon className="icon" width={24} height={24} fill="currentColor" />
      Add to Favorites
    </button>
  );
}

How to do it in Create React App (Legacy)

If you're still on an older CRA setup, the syntax is slightly different. You destructure ReactComponent from the import.

import { ReactComponent as StarIcon } from './assets/star.svg';

function FavoriteButton() {
  return <StarIcon className="icon" />;
}

Why this is the best approach:

  • Clean JSX: Your component files stay readable. No 50-line SVG dumps in your UI code.
  • CSS Styling: Because it renders as actual DOM elements, you can target the SVG with CSS. Using fill="currentColor" is a great trick to make the icon inherit the text color of its parent.
  • Props: You can easily pass dynamic widths, heights, or colors based on your app's state.

Method 2: The Pragmatic Route (Using react-icons)

Best for: Standard UI icons (hamburgers, arrows, social media logos) when you don't have custom designs.

Sometimes you don't have a designer handing you custom SVGs. You just need a standard "trash can" or "user profile" icon. Downloading, optimizing, and importing individual SVG files for every standard UI element is a waste of time.

This is where the react-icons library saves the day. It bundles popular icon sets (Font Awesome, Material Design, Heroicons, etc.) into React components.

First, install it:

npm install react-icons

Then, use it in your code:

import { FaTrash, FaUser } from 'react-icons/fa';
import { MdSearch } from 'react-icons/md';

function Toolbar() {
  return (
    <div className="toolbar">
      <MdSearch size={24} color="gray" />
      <FaUser size={24} />
      <FaTrash size={24} color="red" />
    </div>
  );
}

The secret sauce: react-icons supports tree-shaking. Even though the library contains thousands of icons, your final production bundle will only include the specific icons you actually imported. You don't have to worry about bloating your app size.

Method 3: The Quick & Dirty (Inline SVG)

Best for: One-off, highly specific graphics that you will never need to reuse or style dynamically.

Sometimes you just need to get something on the screen right now, and you don't want to mess with build configurations or file imports. You can just copy the raw SVG code from your .svg file and paste it directly into your JSX.

function WarningBanner() {
  return (
    <div className="banner">
      {/* Just paste the raw SVG code right here */}
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
        <path d="M12 2L1 21h22L12 2zm0 4l7.53 13H4.47L12 6zm-1 5v4h2v-4h-2zm0 6v2h2v-2h-2z" />
      </svg>
      <span>Warning: This action cannot be undone.</span>
    </div>
  );
}

The catch: While this works, it gets messy fast. You have to manually change HTML attributes to JSX attributes (e.g., changing class to className, fill-rule to fillRule). If you have a complex icon with hundreds of paths, your JSX file becomes unreadable. Use this sparingly.

Method 4: The <img> Tag or CSS Background

Best for: Complex illustrations, multi-colored logos, or when you don't need to change the icon's color with CSS.

If your SVG is a complex, multi-colored illustration (like a blank state graphic) and you never need to change its colors via CSS, treat it exactly like a PNG.

// Using an img tag
<img src="/illustrations/empty-state.svg" alt="No data found" />

// Or in your CSS
.my-div {
  background-image: url('/icons/pattern.svg');
}

Why do this? When you use an <img> tag or CSS background, the browser caches the SVG file. If you use the same complex SVG on 50 different pages, the browser only downloads it once. If you import it as a React component (Method 1), that SVG code gets duplicated in your JavaScript bundle 50 times.

So, Which Method Should You Choose?

If you're still confused about how to use SVG icons in React for your specific scenario, here is a quick cheat sheet:

  1. Need a standard UI icon (search, menu, close)? Use react-icons. It’s fast and requires zero setup.
  2. Have a custom icon from your designer that needs to change color? Import it as a React component (Vite ?react or CRA ReactComponent).
  3. Using a complex, multi-colored illustration? Use an <img> tag so the browser can cache it.
  4. In a massive rush and just need it on the screen? Paste it inline, but clean it up later.

3 Pro-Tips for SVGs in React

Before you wrap up, keep these three things in mind to keep your app performant and accessible.

1. Clean your SVGs first

Design tools like Figma and Illustrator export incredibly bloated SVG code filled with metadata and unnecessary groups. Before importing an SVG into your React app, run it through a tool like SVGOMG. It strips out the junk and can reduce your file size by 50% or more.

2. Make them accessible

Screen readers need to know what your icons mean. If your icon conveys meaning (like a trash can that deletes an item), add an aria-label. If it’s purely decorative, hide it from screen readers.

// Meaningful icon
<button aria-label="Delete item">
  <TrashIcon />
</button>

// Decorative icon (next to text that already explains it)
<button>
  <TrashIcon aria-hidden="true" />
  Delete
</button>

3. Use 1em for sizing

If you want your icons to scale perfectly with your text, set their default width and height to 1em inside the SVG file itself, rather than hardcoding 24px. This way, if you put the icon inside an <h1> tag, it automatically grows. If it's in a small caption, it shrinks.


Handling SVGs in React doesn't have to be a chore. By picking the right method for the right job—whether that's leveraging react-icons for speed, importing components for dynamic styling, or using <img> tags for caching—you'll keep your codebase clean and your app running fast.

Now go clean up those messy inline SVGs in your codebase!