How to Add Icons to a Next.js App (App Router)
Step-by-step guide to installing and using SVG icon components in a Next.js 14/15 App Router project, including Server Components, Client Components, and performance tips.
Adding icons to a Next.js project is straightforward, but a few details trip people up — especially with the App Router's split between Server and Client Components. This guide covers everything from install to optimised production bundle.
Install krz-icons
npm install krz-icons
# or
yarn add krz-icons
# or
pnpm add krz-icons
# or
bun add krz-icons
The package ships a tree-shakeable ESM build, a CommonJS build, TypeScript type definitions, and raw SVG files. React (≥ 16.8) is listed as an optional peer dependency — you only need it if you use the React components.
Using icons in Server Components
krz-icons components work in React Server Components out of the box. No "use client" directive is needed on the component itself.
// app/page.tsx (Server Component)
import { Home, ArrowRight } from "krz-icons";
export default function Page() {
return (
<main>
<Home size={24} />
<p>Welcome <ArrowRight size={16} /></p>
</main>
);
}
Icons render to static HTML on the server. No JavaScript is sent to the client for the icons themselves.
Using icons in Client Components
Client Components work the same way — just import and use.
"use client";
import { useState } from "react";
import { Bell, BellOff } from "krz-icons";
export function NotificationToggle() {
const [on, setOn] = useState(true);
return (
<button onClick={() => setOn(!on)}>
{on ? <Bell size={20} /> : <BellOff size={20} />}
</button>
);
}
Customising icons
Every icon accepts size, color, and strokeWidth props, and forwards everything else to the underlying <svg>.
// Larger, branded color, thicker stroke
<Search size={32} color="#06D6A0" strokeWidth={1.5} />
// Match text color (default)
<Home />
// Accessible labelled icon
<button aria-label="Go home">
<Home size={20} />
</button>
Keeping your bundle small
Import only the icons you use. Named imports from the package root are tree-shaken by Next.js's webpack/Turbopack bundler automatically.
// ✅ Tree-shaken — only Bell and Home end up in the bundle
import { Bell, Home } from "krz-icons";
// ⚠️ Imports the entire library — avoid in components
import * as Icons from "krz-icons";
If you have a dynamic icon picker where the icon name is only known at runtime, use the per-icon import path:
// Imports just the one icon
import HomeIcon from "krz-icons/icons/home";
Using the raw SVG files
If you need static SVG assets — for example in an <img> tag or as a CSS background-image — the SVG files ship in the package.
// next.config.ts — allow SVG imports
import type { NextConfig } from "next";
const config: NextConfig = {};
export default config;
// In a component (requires a webpack SVG loader)
import homeUrl from "krz-icons/svg/home.svg";
Alternatively, copy the SVG markup from the icon gallery and inline it.
TypeScript autocomplete
krz-icons ships .d.ts files, so VS Code and other TypeScript-aware editors show autocomplete for every icon name. Start typing the component name and hit Tab.
You can also use the KrzIcon type to annotate props that accept any icon component:
import type { KrzIcon } from "krz-icons";
function Button({ icon: Icon, label }: { icon: KrzIcon; label: string }) {
return (
<button>
<Icon size={16} /> {label}
</button>
);
}
Summary
Three steps to use icons in Next.js: install krz-icons, import the icons you need by name, and use them like any React component. Server Components, Client Components, and static HTML all work without any configuration.