Comprehensive ecosystem of 5,945 free MIT-licensed SVG icons with framework components for React, Vue, Svelte and raw SVG files.
—
Svelte component library providing tree-shakable components for all 5,945 Tabler Icons with full TypeScript support. Each icon is available as an optimized Svelte component with reactive props and consistent interfaces.
npm install @tabler/icons-svelteimport { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-svelte';Tree-shakable imports for individual icon components with full TypeScript support and Svelte reactivity.
/**
* Individual icon component imports
* Pattern: Icon{PascalCaseName} for outline icons
* Pattern: Icon{PascalCaseName}Filled for filled icons
*/
import { IconHome } from '@tabler/icons-svelte';
import { IconHeart } from '@tabler/icons-svelte';
import { IconHeartFilled } from '@tabler/icons-svelte';
import { IconArrowLeft } from '@tabler/icons-svelte';
interface IconProps {
/** Icon size in pixels (applies to both width and height) */
size?: number;
/** Icon stroke color (outline icons) or fill color (filled icons) */
color?: string;
/** Stroke width for outline icons */
stroke?: number;
/** CSS class name */
class?: string;
}Usage Examples:
<script lang="ts">
import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-svelte';
let iconSize = 24;
let heartColor = 'red';
let isActive = false;
</script>
<main>
<!-- Basic usage -->
<IconHome />
<!-- With custom props -->
<IconHeart
size={32}
color={heartColor}
stroke={1.5}
class="heart-icon"
/>
<!-- With reactive props -->
<IconArrowLeft
size={iconSize}
color={isActive ? 'blue' : 'gray'}
on:click={() => history.back()}
/>
<!-- With dynamic class -->
<IconHome
class={isActive ? 'active' : 'inactive'}
size={isActive ? 32 : 24}
/>
</main>
<style>
.heart-icon {
cursor: pointer;
transition: transform 0.2s;
}
.heart-icon:hover {
transform: scale(1.1);
}
.active {
color: #3b82f6;
}
.inactive {
color: #6b7280;
}
</style>Comprehensive prop interface for customizing icon appearance and behavior with Svelte reactivity.
interface IconProps {
/**
* Icon size in pixels (applies to both width and height)
* @default 24
*/
size?: number;
/**
* Icon stroke color (outline icons) or fill color (filled icons)
* @default "currentColor"
*/
color?: string;
/**
* Stroke width for outline icons
* @default 2
*/
stroke?: number;
/**
* CSS class name applied to the SVG element
* Can be reactive
*/
class?: string;
}
// Event handlers (available on all icon components)
interface IconEvents {
/** Click event handler */
on:click?: (event: MouseEvent) => void;
/** Mouse enter event handler */
on:mouseenter?: (event: MouseEvent) => void;
/** Mouse leave event handler */
on:mouseleave?: (event: MouseEvent) => void;
}Usage Examples:
<script lang="ts">
import { IconUser, IconSettings, IconHome } from '@tabler/icons-svelte';
let dynamicSize = 24;
let strokeWidth = 2;
let themeColor = '#3b82f6';
let isHovered = false;
let isError = false;
function handleClick() {
console.log('Icon clicked');
}
function handleHover() {
isHovered = true;
}
function handleLeave() {
isHovered = false;
}
</script>
<div>
<!-- Size variations -->
<IconUser size={16} /> <!-- Small -->
<IconUser size={24} /> <!-- Default -->
<IconUser size={32} /> <!-- Large -->
<IconUser size={dynamicSize} /> <!-- Reactive -->
<!-- Color variations -->
<IconSettings color="#3b82f6" />
<IconSettings color="rgb(239, 68, 68)" />
<IconSettings color={themeColor} />
<!-- Stroke width variations -->
<IconHome stroke={1} /> <!-- Thin -->
<IconHome stroke={3} /> <!-- Thick -->
<IconHome stroke={strokeWidth} /> <!-- Reactive -->
<!-- CSS classes -->
<IconSettings class="settings-icon rotating" />
<IconSettings class={isHovered ? 'hovered' : ''} />
<!-- Event handlers -->
<IconSettings
on:click={handleClick}
on:mouseenter={handleHover}
on:mouseleave={handleLeave}
class={isHovered ? 'hovered' : ''}
/>
<!-- Conditional styling -->
<IconSettings
color={isError ? 'red' : 'blue'}
size={isError ? 32 : 24}
class={isError ? 'error' : 'normal'}
/>
</div>
<style>
.settings-icon {
cursor: pointer;
transition: transform 0.2s;
}
.rotating {
animation: spin 2s linear infinite;
}
.hovered {
transform: scale(1.1);
}
.error {
filter: drop-shadow(0 0 4px red);
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>Access to both outline (stroke-based) and filled (solid) icon variants with different naming conventions.
/**
* Icon naming conventions:
* - Outline icons: Icon{PascalCaseName} (default style)
* - Filled icons: Icon{PascalCaseName}Filled
*
* Examples:
* - IconHome (outline) vs IconHomeFilled (filled)
* - IconHeart (outline) vs IconHeartFilled (filled)
* - IconStar (outline) vs IconStarFilled (filled)
*/
// Outline icons (4,964 available)
import {
IconHome,
IconHeart,
IconStar,
IconUser,
IconSettings
} from '@tabler/icons-svelte';
// Filled icons (981 available)
import {
IconHomeFilled,
IconHeartFilled,
IconStarFilled,
IconUserFilled,
IconSettingsFilled
} from '@tabler/icons-svelte';Usage Examples:
<script lang="ts">
import {
IconHeart,
IconHeartFilled,
IconStar,
IconStarFilled,
IconCheckCircle,
IconCheckCircleFilled
} from '@tabler/icons-svelte';
let isFavorite = false;
let rating = 0;
let isCompleted = false;
function toggleFavorite() {
isFavorite = !isFavorite;
}
function setRating(value: number) {
rating = value;
}
</script>
<div>
<!-- Toggle between outline and filled -->
<button on:click={toggleFavorite}>
{#if isFavorite}
<IconHeartFilled color="red" />
{:else}
<IconHeart color="gray" />
{/if}
{isFavorite ? 'Favorited' : 'Favorite'}
</button>
<!-- Star rating component -->
<div class="rating">
{#each [1, 2, 3, 4, 5] as value}
<button on:click={() => setRating(value)}>
{#if value <= rating}
<IconStarFilled color="gold" />
{:else}
<IconStar color="gray" />
{/if}
</button>
{/each}
</div>
<!-- Conditional icon rendering -->
{#if isCompleted}
<IconCheckCircleFilled color="green" />
{:else}
<IconCheckCircle color="gray" />
{/if}
</div>
<style>
.rating {
display: flex;
gap: 0.25rem;
}
.rating button {
background: none;
border: none;
cursor: pointer;
padding: 0.25rem;
border-radius: 0.25rem;
transition: background-color 0.2s;
}
.rating button:hover {
background-color: #f3f4f6;
}
</style>Deep integration with Svelte stores for reactive icon properties and global state management.
/**
* Svelte stores integration patterns
* Icons work seamlessly with writable, readable, and derived stores
*/
import { writable, derived } from 'svelte/store';
// Theme store example
const theme = writable('light');
const iconColor = derived(theme, $theme => $theme === 'dark' ? '#ffffff' : '#000000');
const iconSize = derived(theme, $theme => $theme === 'dark' ? 28 : 24);
// Animation store example
const isAnimating = writable(false);
const rotation = writable(0);Usage Examples:
<script lang="ts">
import { writable, derived } from 'svelte/store';
import {
IconSun,
IconMoon,
IconLoader,
IconCheck,
IconX,
IconClock
} from '@tabler/icons-svelte';
// Theme store
const isDark = writable(false);
const iconColor = derived(isDark, $isDark => $isDark ? '#ffffff' : '#000000');
const iconSize = derived(isDark, $isDark => $isDark ? 28 : 24);
function toggleTheme() {
isDark.update(dark => !dark);
}
// Loading state store
const isLoading = writable(false);
const rotation = writable(0);
// Auto-rotate when loading
$: if ($isLoading) {
const interval = setInterval(() => {
rotation.update(r => r + 90);
}, 200);
// Cleanup when not loading
const unsubscribe = isLoading.subscribe(loading => {
if (!loading) {
clearInterval(interval);
unsubscribe();
}
});
}
// Status store
const status = writable('pending'); // 'success' | 'error' | 'pending'
const statusIcon = derived(status, $status => {
switch ($status) {
case 'success': return IconCheck;
case 'error': return IconX;
default: return IconClock;
}
});
const statusColor = derived(status, $status => {
switch ($status) {
case 'success': return 'green';
case 'error': return 'red';
default: return 'gray';
}
});
</script>
<div>
<!-- Theme-aware icons -->
<button on:click={toggleTheme}>
{#if $isDark}
<IconMoon color={$iconColor} size={$iconSize} />
{:else}
<IconSun color={$iconColor} size={$iconSize} />
{/if}
Toggle Theme
</button>
<!-- Animated loading icon -->
<IconLoader
style="transform: rotate({$rotation}deg); transition: transform 0.5s ease"
class={$isLoading ? 'spinning' : ''}
/>
<!-- Status-based icons -->
<svelte:component
this={$statusIcon}
color={$statusColor}
size={24}
/>
</div>
<style>
.spinning {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>Advanced patterns for composing icon components with other Svelte components and logic.
/**
* Component composition patterns
* Creating reusable icon-based components with slots and props
*/
// Icon button component interface
interface IconButtonProps {
icon: any; // Svelte component
variant?: 'primary' | 'secondary' | 'ghost';
size?: 'sm' | 'md' | 'lg';
disabled?: boolean;
}
// Icon with tooltip interface
interface IconTooltipProps {
icon: any;
tooltip: string;
position?: 'top' | 'bottom' | 'left' | 'right';
}Usage Examples:
<!-- IconButton.svelte -->
<script lang="ts">
export let icon: any;
export let variant: 'primary' | 'secondary' | 'ghost' = 'primary';
export let size: 'sm' | 'md' | 'lg' = 'md';
export let disabled = false;
$: iconSize = size === 'sm' ? 16 : size === 'lg' ? 24 : 20;
$: buttonClass = `btn btn-${variant} btn-${size}`;
</script>
<button
class={buttonClass}
{disabled}
on:click
>
<svelte:component this={icon} size={iconSize} />
<slot />
</button>
<style>
.btn {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
cursor: pointer;
transition: all 0.2s;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn-primary {
background-color: #3b82f6;
color: white;
}
.btn-secondary {
background-color: #6b7280;
color: white;
}
.btn-ghost {
background-color: transparent;
color: currentColor;
}
.btn-sm {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
}
.btn-lg {
padding: 0.75rem 1.5rem;
font-size: 1.125rem;
}
</style>
<!-- Usage of IconButton -->
<script lang="ts">
import IconButton from './IconButton.svelte';
import { IconTrash, IconEdit, IconPlus } from '@tabler/icons-svelte';
function handleAdd() {
console.log('Add clicked');
}
function handleEdit() {
console.log('Edit clicked');
}
function handleDelete() {
console.log('Delete clicked');
}
</script>
<div class="actions">
<IconButton icon={IconPlus} variant="primary" on:click={handleAdd}>
Add Item
</IconButton>
<IconButton icon={IconEdit} variant="secondary" on:click={handleEdit}>
Edit
</IconButton>
<IconButton icon={IconTrash} variant="ghost" on:click={handleDelete}>
Delete
</IconButton>
</div>
<style>
.actions {
display: flex;
gap: 0.5rem;
}
</style>Load icons dynamically based on string identifiers with TypeScript safety and performance optimization.
<script lang="ts">
import type { ComponentType } from 'svelte';
// Icon registry for dynamic loading
const iconRegistry: Record<string, () => Promise<{ default: ComponentType }>> = {
home: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconHome })),
user: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconUser })),
settings: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconSettings })),
};
export let iconName: string;
export let size = 24;
export let color = 'currentColor';
let IconComponent: ComponentType | null = null;
let loading = false;
let error = false;
$: loadIcon(iconName);
async function loadIcon(name: string) {
if (!iconRegistry[name]) {
error = true;
return;
}
loading = true;
error = false;
try {
const module = await iconRegistry[name]();
IconComponent = module.default;
} catch (err) {
error = true;
console.warn(`Failed to load icon: ${name}`, err);
} finally {
loading = false;
}
}
</script>
{#if loading}
<div class="icon-placeholder loading" style="width: {size}px; height: {size}px;" />
{:else if error}
<div class="icon-placeholder error" style="width: {size}px; height: {size}px;" />
{:else if IconComponent}
<svelte:component this={IconComponent} {size} {color} />
{/if}
<style>
.icon-placeholder {
display: inline-block;
border-radius: 0.25rem;
animation: pulse 1.5s ease-in-out infinite;
}
.loading {
background-color: #e5e7eb;
}
.error {
background-color: #fca5a5;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
</style>Create animated icon components using Svelte's built-in animation capabilities.
<script lang="ts">
import { fade, scale, fly } from 'svelte/transition';
import { IconCheck, IconX, IconLoader } from '@tabler/icons-svelte';
export let status: 'loading' | 'success' | 'error' = 'loading';
export let size = 24;
$: icon = status === 'success' ? IconCheck :
status === 'error' ? IconX :
IconLoader;
$: color = status === 'success' ? 'green' :
status === 'error' ? 'red' :
'gray';
</script>
<div class="status-icon">
{#key status}
<svelte:component
this={icon}
{size}
{color}
class={status === 'loading' ? 'spinning' : ''}
in:scale={{ duration: 300 }}
out:fade={{ duration: 200 }}
/>
{/key}
</div>
<style>
.status-icon {
display: inline-block;
}
.spinning {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>Create icon grid interfaces for icon selection and display.
<script lang="ts">
import * as TablerIcons from '@tabler/icons-svelte';
export let selectedIcon: string | null = null;
export let onSelect: (iconName: string) => void = () => {};
// Get all available icons
const iconEntries = Object.entries(TablerIcons).filter(([name]) =>
name.startsWith('Icon') && !name.includes('Filled')
);
function handleIconClick(iconName: string) {
selectedIcon = iconName;
onSelect(iconName);
}
</script>
<div class="icon-grid">
{#each iconEntries as [iconName, IconComponent]}
<button
class="icon-card"
class:selected={selectedIcon === iconName}
on:click={() => handleIconClick(iconName)}
>
<svelte:component this={IconComponent} size={32} />
<span class="icon-name">{iconName.replace('Icon', '')}</span>
</button>
{/each}
</div>
<style>
.icon-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 0.5rem;
padding: 1rem;
}
.icon-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
padding: 1rem;
background: white;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
cursor: pointer;
transition: all 0.2s;
}
.icon-card:hover {
background-color: #f9fafb;
transform: translateY(-2px);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.icon-card.selected {
border-color: #3b82f6;
background-color: #eff6ff;
}
.icon-name {
font-size: 0.875rem;
text-align: center;
color: #6b7280;
}
</style>Install with Tessl CLI
npx tessl i tessl/npm-tabler--icons