Tabler Icons: The Complete React Guide (5,000+ Free Icons)
Everything about @tabler/icons-react — installation, tree-shaking, stroke customization, IconCustomize wrapper, and why Tabler is the best free icon library for dashboards in 2026.
Tabler Icons is the largest consistent free icon library available in 2026 — over 5,000 outline icons, MIT licensed, all on a 24px grid with a 1.5px stroke. For dashboards, admin panels, and SaaS products that need deep icon coverage, it’s the practical choice over Lucide’s 1,500 or Heroicons’ 292.
This guide goes beyond “npm install” and covers the full Tabler API: stroke customization, the IconCustomize wrapper, bundle optimization, and the patterns that make Tabler icons feel polished in production.
Why Tabler over other large sets
| Library | Icons | Stroke control | MIT | Active in 2026 |
|---|---|---|---|---|
| Tabler | 5,000+ | strokeWidth prop | Yes | Yes |
| Remix Icons | 2,800+ | None | Apache 2.0 | Slow |
| Carbon | 2,100+ | Fixed | Apache 2.0 | Yes |
| Bootstrap Icons | 2,200+ | CSS only | MIT | Yes |
The strokeWidth prop is what separates Tabler from the rest of the large sets. You can control visual weight per-icon or globally, making it adaptable to different UI densities.
Installation
npm install @tabler/icons-react
# or
pnpm add @tabler/icons-react
Minimum requirements: React 16.8+, Tabler 3.x requires React 18+.
Basic usage
Every Tabler icon is a named export from @tabler/icons-react:
import { IconDashboard, IconUsers, IconSettings } from '@tabler/icons-react';
export function AppNav() {
return (
<nav className="flex gap-4">
<IconDashboard size={20} />
<IconUsers size={20} />
<IconSettings size={20} />
</nav>
);
}
Props reference
| Prop | Type | Default | Description |
|---|---|---|---|
size | number | string | 24 | Width and height in pixels |
color | string | currentColor | Stroke color |
stroke | number | 2 | Stroke width |
strokeWidth | number | — | Alias for stroke |
className | string | — | CSS class |
style | CSSProperties | — | Inline styles |
Tabler uses the SVG attribute name stroke as the prop, not strokeWidth like Lucide. Both are accepted but stroke is canonical. When migrating from Lucide, find/replace strokeWidth with stroke.
Stroke width — Tabler’s superpower
The default stroke is 2, but Tabler icons look excellent at 1.5 for lighter, more editorial UIs and 2.5 for bold, high-contrast UIs.
// Light, editorial style
<IconDashboard size={24} stroke={1.5} />
// Standard (default)
<IconDashboard size={24} stroke={2} />
// Bold, high-contrast
<IconDashboard size={24} stroke={2.5} />
Setting a global default stroke
Instead of passing stroke to every icon, use Tabler’s IconContext:
import { IconContext } from '@tabler/icons-react';
// Wrap your entire app or a subtree
export function App() {
return (
<IconContext.Provider value={{ stroke: 1.5, size: 20 }}>
<YourApp />
</IconContext.Provider>
);
}
All icons inside the provider inherit the stroke and size values unless overridden individually.
The IconCustomize wrapper
For icons that need custom behavior beyond what props provide — wrapping with animations, adding ARIA attributes, combining with badge counts — use IconCustomize:
import { IconBell, IconCustomize } from '@tabler/icons-react';
// Badge notification icon
function NotificationIcon({ count }) {
return (
<div className="relative">
<IconBell size={22} />
{count > 0 && (
<span className="absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center
rounded-full bg-red-500 text-[10px] font-bold text-white">
{count > 9 ? '9+' : count}
</span>
)}
</div>
);
}
For a reusable wrapper that passes through all Tabler props:
import type { TablerIconsProps } from '@tabler/icons-react';
interface IconWrapperProps extends TablerIconsProps {
icon: React.FC<TablerIconsProps>;
label?: string;
}
function Icon({ icon: TablerIcon, label, ...props }: IconWrapperProps) {
return (
<TablerIcon
aria-hidden={!label}
aria-label={label}
role={label ? 'img' : undefined}
{...props}
/>
);
}
Tree-shaking and bundle size
Tabler ships as a proper ES module package with "sideEffects": false, so named imports are fully tree-shaken by Vite, Next.js Turbopack, and Webpack 5.
// ✅ Only bundles IconDashboard and IconSettings (~0.4KB each)
import { IconDashboard, IconSettings } from '@tabler/icons-react';
// ❌ Bundles the entire library (~8MB) — never do this
import * as Icons from '@tabler/icons-react';
Bundle size benchmarks (per icon, gzipped)
| Icon | Raw size | Gzipped |
|---|---|---|
| Single Tabler icon | ~1.2KB | ~0.4KB |
| 10 Tabler icons | ~12KB | ~3.5KB |
| 50 Tabler icons | ~60KB | ~16KB |
For 50+ icons in a dashboard, 16KB gzipped is negligible — but always import by name to let the bundler eliminate what you don’t use.
Run ANALYZE=true pnpm build in a Next.js project with @next/bundle-analyzer installed to confirm Tabler icons are being tree-shaken. You should see individual icon modules, not a single large chunk.
Building a Tabler icon system in a design system
For a product that uses Tabler as its primary icon library, wrap it in a thin abstraction:
// src/components/icons/index.ts
export {
IconDashboard as Dashboard,
IconUsers as Users,
IconSettings as Settings,
IconBell as Bell,
IconSearch as Search,
// ... re-export with semantic names
} from '@tabler/icons-react';
export type { TablerIconsProps as IconProps } from '@tabler/icons-react';
Then use a single import path throughout the app:
import { Dashboard, Users, Settings } from '@/components/icons';
This decouples your components from the Tabler package — if you ever swap libraries, you change only src/components/icons/index.ts.
Tabler for dashboards: icon vocabulary
Dashboards need a consistent icon vocabulary. Here’s a recommended mapping for the most common dashboard concepts:
| Concept | Recommended icon |
|---|---|
| Overview / home | IconLayoutDashboard |
| Line chart / trend | IconChartLine |
| Bar chart | IconChartBar |
| Pie / donut | IconChartPie |
| Table view | IconTable |
| Filter | IconFilter |
| Sort | IconSortAscending / IconSortDescending |
| Export | IconDownload |
| Refresh | IconRefresh |
| Row actions | IconDotsVertical |
Accessibility
Tabler icons are decorative by default — all paths have no role or title. Follow the same patterns as any other SVG icon library:
// Decorative icon in labeled button
<button>
<IconDownload size={18} aria-hidden="true" />
Export CSV
</button>
// Standalone meaningful icon
<IconAlertTriangle
size={20}
role="img"
aria-label="Warning"
className="text-yellow-500"
/>
// Icon-only button
<button aria-label="Delete row">
<IconTrash size={18} aria-hidden="true" />
</button>
Dark mode
Tabler icons use currentColor on all strokes. Set color via the parent’s CSS color property:
<div className="text-gray-700 dark:text-gray-300">
<IconSettings size={20} />
</div>
Or pass color directly:
<IconSettings size={20} color="var(--icon-default)" />
Frequently asked questions
How do I search 5,000+ Tabler icons? Browse all icons at tablericons.com or search directly on AllSVGIcons by filtering for the Tabler pack — every icon links back to its Iconify ID for use in React.
Does Tabler have filled variants?
Tabler 3.0 introduced filled variants for a subset of icons. Import the filled version by appending Filled:
import { IconHeartFilled, IconStarFilled } from '@tabler/icons-react';
Can I use Tabler with Vue or Svelte?
Yes. @tabler/icons-vue and @tabler/icons-svelte are maintained alongside the React package with the same API.
Related Reading
- Best Free SVG Icon Libraries 2026 – The Definitive Comparison
- SVG Icons for Dashboards
- How to Build a Custom SVG Icon Component Library in React and Next.js
- SVG Icons in Dark Mode: The Complete Tailwind & CSS Guide
- Heroicons vs Tabler Icons – Which to Use in 2026?
- Tabler Icons vs Font Awesome – Modernizing Your UI