Managing SVG Icons in React & Next.js: The Complete Guide

Managing SVG Icons in React & Next.js: The Complete Guide
Icons from different sources? Legacy SVGs as images? Learn how to properly manage, organize, and use SVG icons in modern React and Next.js projects.
Mohammad Alhabil
Author
Managing SVG Icons in React & Next.js: The Complete Guide
How many times have you received a design with icons from a million sources?
You opened the design and found Remix, Feather, Material, and random SVGs all mixed in the same design!
Let's go through the most common problems and how to solve them as developers...
1️⃣ Legacy Project with SVGs Used as Images
Found this everywhere?
<img src="/icons/star.svg" alt="star" />
Want to change the icon color or stroke? Impossible... because you've treated it as an image, losing all SVG advantages.
The Problem
You might think: "I'll copy the SVG code and replace <img> everywhere."
But wait... if the same icon is repeated in 20 places? Copy the code 20 times?!
❌ Code becomes a mess ❌ Hard to maintain ❌ Bundle size increases
The Solution: SVGInject
A lightweight and smart tool that converts any <img src="icon.svg"> inside the DOM to a real <svg>:
<img class="inject-me" src="/icon.svg" />
<script src="https://unpkg.com/@iconfu/svg-inject"></script>
<script>
SVGInject(document.querySelectorAll('.inject-me'));
</script>
Now you can modify it with CSS!
.inject-me path {
fill: #3b82f6;
stroke: #1e40af;
}
⚠️ Note: For large numbers of icons, dynamic DOM manipulation can affect performance. Use it wisely for medium or quick projects.
2️⃣ New Project with Icons from Different Sources
The designer sent you 50 icons from Remix, Material, Feather, and others?
The Smart Solution: IcoMoon
- Collect all icons and upload them to icomoon.io
- Unify styles and sizes
- Rename icons for consistency
- Remove unwanted icons
- Export as Font or SVG Folder
Benefits
| Feature | Description |
|---|---|
| 🎨 Unified Style | All icons look consistent |
| 📁 Single Source | One library for everything |
| 🔧 Customizable | Edit before export |
| 📦 Optimized | Only include what you need |
3️⃣ React/Next.js: SVGs as Components
As React developers, we love everything to be:
- ✅ JSX
- ✅ Customizable
- ✅ Reusable
Using icomoon-react
- Export from IcoMoon → Select "Generate SVG"
- Find
selection.jsonin the folder - Use with
icomoon-react:
npm install icomoon-react
import IcoMoon from 'icomoon-react';
import iconSet from './selection.json';
interface IconProps {
icon: string;
size?: number;
color?: string;
}
export function Icon({ icon, size = 24, color = 'currentColor' }: IconProps) {
return (
<IcoMoon
iconSet={iconSet}
icon={icon}
size={size}
color={color}
/>
);
}
// Usage
<Icon icon="star" size={24} color="#f59e0b" />
<Icon icon="heart" size={32} color="#ef4444" />
Why This is Better
<img> Approach | Component Approach |
|---|---|
| Can't change colors | Full color control |
| No SSR benefits | SSR compatible |
| Extra HTTP requests | Bundled with JS |
| Hard to maintain | Easy to reuse |
4️⃣ Best Icon Libraries in 2025
Starting from scratch? Here are the best options:
Lucide Icons
npm install lucide-react
import { Star, Heart, User } from 'lucide-react';
<Star size={24} color="#f59e0b" />
✅ Very lightweight, excellent React support
Heroicons
npm install @heroicons/react
import { StarIcon } from '@heroicons/react/24/solid';
<StarIcon className="h-6 w-6 text-yellow-500" />
✅ Perfect with Tailwind CSS
Tabler Icons
npm install @tabler/icons-react
✅ Ideal for dashboards
Phosphor Icons
npm install @phosphor-icons/react
✅ Huge library with multiple styles (thin, light, regular, bold, fill, duotone)
Comparison Table
| Library | Icons | Styles | Size | Best For |
|---|---|---|---|---|
| Lucide | 1400+ | 1 | ~1KB each | General use |
| Heroicons | 300+ | 2 | ~1KB each | Tailwind projects |
| Tabler | 4000+ | 1 | ~1KB each | Dashboards |
| Phosphor | 7000+ | 6 | ~2KB each | Variety needed |
| Iconoir | 1300+ | 1 | ~1KB each | Modern designs |
Tips from Experience
1. Create a Unified Icon Component
// components/Icon.tsx
import * as LucideIcons from 'lucide-react';
type IconName = keyof typeof LucideIcons;
interface IconProps {
name: IconName;
size?: number;
className?: string;
}
export function Icon({ name, size = 24, className }: IconProps) {
const LucideIcon = LucideIcons[name] as React.ComponentType<any>;
if (!LucideIcon) {
console.warn(`Icon "${name}" not found`);
return null;
}
return <LucideIcon size={size} className={className} />;
}
// Usage
<Icon name="Star" size={24} className="text-yellow-500" />
2. Optimize SVGs Before Using
Use SVGOMG to:
- Remove unnecessary metadata
- Optimize paths
- Reduce file size by 50-80%
3. Consistent Sizing
If icons have inconsistent sizes, organize them in IcoMoon before export:
- Align
- Center
- Resize to consistent viewBox
Quick Decision Guide
| Situation | Solution |
|---|---|
🏚️ Legacy project with <img> SVGs | SVGInject |
| 🆕 New project, mixed icon sources | IcoMoon |
| ⚛️ React/Next.js project | icomoon-react or Lucide |
| 🎨 Starting from scratch | Pick from recommended libraries |
Resources
- 🔗 SVGInject
- 🔗 IcoMoon
- 🔗 icomoon-react
- 🔗 SVGOMG
- 🔗 Lucide Icons
- 🔗 Heroicons
- 🔗 Phosphor Icons
Interfaces you love, code you understand. 💡
Topics covered
Found this article helpful?
Share it with your network and help others learn too!

Written by Mohammad Alhabil
Frontend Developer & Software Engineer passionate about building beautiful and functional web experiences. I write about React, Next.js, and modern web development.
Related Articles
View all
Props vs State vs Context vs Ref: When to Use Each in React
Confused about when to use Props, State, Context, or Ref? Misusing them doesn't just slow performance—it creates tangled code that's hard to debug. Let's clear things up once and for all.

Understanding React Re-renders: Virtual DOM, Diffing & Reconciliation
We're all afraid of re-renders. But is this fear justified? Learn how React actually handles changes under the hood and why not every render is a disaster.

Why useState Isn't Always the Answer: URL State vs React State
There's a simple pattern that can change how you handle UI, achieve better performance, maintain SEO, and create a cleaner interface. Learn when to use URL instead of useState.