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.

Amit Yadav
Amit Yadav

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

LibraryIconsStroke controlMITActive in 2026
Tabler5,000+strokeWidth propYesYes
Remix Icons2,800+NoneApache 2.0Slow
Carbon2,100+FixedApache 2.0Yes
Bootstrap Icons2,200+CSS onlyMITYes

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

PropTypeDefaultDescription
sizenumber | string24Width and height in pixels
colorstringcurrentColorStroke color
strokenumber2Stroke width
strokeWidthnumberAlias for stroke
classNamestringCSS class
styleCSSPropertiesInline styles
stroke vs strokeWidth

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)

IconRaw sizeGzipped
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.

Check your bundle with @next/bundle-analyzer

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:

ConceptRecommended icon
Overview / homeIconLayoutDashboard
Line chart / trendIconChartLine
Bar chartIconChartBar
Pie / donutIconChartPie
Table viewIconTable
FilterIconFilter
SortIconSortAscending / IconSortDescending
ExportIconDownload
RefreshIconRefresh
Row actionsIconDotsVertical

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.

Share this post