Comprehensive ecosystem of 5,945 free MIT-licensed SVG icons with framework components for React, Vue, Svelte and raw SVG files.
—
Vue component library providing tree-shakable components for all 5,945 Tabler Icons with full Vue 3 support. Each icon is available as an optimized Vue component with reactive props and consistent interfaces.
npm install @tabler/icons-vue<script setup>
import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';
</script>Or with Options API:
<script>
import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';
export default {
components: { IconHome, IconHeart, IconArrowLeft }
};
</script>Tree-shakable imports for individual icon components with full Vue 3 composition and options API support.
/**
* Individual icon component imports
* Pattern: Icon{PascalCaseName} for outline icons
* Pattern: Icon{PascalCaseName}Filled for filled icons
*/
import { IconHome } from '@tabler/icons-vue';
import { IconHeart } from '@tabler/icons-vue';
import { IconHeartFilled } from '@tabler/icons-vue';
import { IconArrowLeft } from '@tabler/icons-vue';
interface IconProps {
/** Icon size in pixels (applies to both width and height) */
size?: string | number;
/** Icon stroke color (outline icons) or fill color (filled icons) */
color?: string;
/** Alias for color prop */
stroke?: string;
/** Stroke width for outline icons */
strokeWidth?: string | number;
/** CSS class name */
class?: string;
/** Inline styles */
style?: string | object;
}Usage Examples:
<template>
<div>
<!-- Basic usage -->
<IconHome />
<!-- With custom props -->
<IconHeart
size="32"
color="red"
stroke-width="1.5"
class="heart-icon"
/>
<!-- With event handlers -->
<IconArrowLeft
size="24"
@click="goBack"
style="cursor: pointer"
/>
<!-- Reactive props -->
<IconHome
:size="iconSize"
:color="theme.primary"
:stroke-width="strokeWidth"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';
const iconSize = ref(24);
const strokeWidth = ref(2);
const theme = { primary: '#3b82f6' };
const goBack = () => {
history.back();
};
</script>Comprehensive prop interface for customizing icon appearance and behavior with Vue reactivity.
interface IconProps {
/**
* Icon size in pixels (applies to both width and height)
* @default 24
*/
size?: string | number;
/**
* Icon stroke color (outline icons) or fill color (filled icons)
* @default "currentColor"
*/
color?: string;
/**
* Alias for color prop - icon stroke color
* @default "currentColor"
*/
stroke?: string;
/**
* Stroke width for outline icons
* @default 2
*/
strokeWidth?: string | number;
/**
* CSS class name applied to the SVG element
* Can be string or reactive ref
*/
class?: string;
/**
* Inline styles applied to the SVG element
* Can be string, object, or reactive ref
*/
style?: string | Record<string, any>;
}Usage Examples:
<template>
<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 stroke="rgb(239, 68, 68)" />
<IconSettings :color="themeColor" />
<!-- Stroke width -->
<IconHome stroke-width="1" /> <!-- Thin -->
<IconHome stroke-width="3" /> <!-- Thick -->
<IconHome :stroke-width="weight" /> <!-- Reactive -->
<!-- CSS classes -->
<IconSettings class="settings-icon rotating" />
<IconSettings :class="{ active: isActive }" />
<!-- Inline styles -->
<IconSettings style="cursor: pointer; transition: transform 0.2s;" />
<IconSettings :style="{ color: isError ? 'red' : 'blue' }" />
<!-- Event handlers -->
<IconSettings
@click="toggleSettings"
@mouseenter="onHover"
@mouseleave="onLeave"
/>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import { IconUser, IconSettings, IconHome } from '@tabler/icons-vue';
const dynamicSize = ref(24);
const weight = ref(2);
const isActive = ref(false);
const isError = ref(false);
const themeColor = computed(() => isActive.value ? '#3b82f6' : '#6b7280');
const toggleSettings = () => {
console.log('Settings toggled');
};
const onHover = () => {
console.log('Icon hovered');
};
const onLeave = () => {
console.log('Icon left');
};
</script>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-vue';
// Filled icons (981 available)
import {
IconHomeFilled,
IconHeartFilled,
IconStarFilled,
IconUserFilled,
IconSettingsFilled
} from '@tabler/icons-vue';Usage Examples:
<template>
<div>
<!-- Toggle between outline and filled -->
<button @click="toggleFavorite">
<IconHeartFilled v-if="isFavorite" color="red" />
<IconHeart v-else color="gray" />
</button>
<!-- Star rating component -->
<div class="rating">
<template v-for="value in [1, 2, 3, 4, 5]" :key="value">
<button @click="setRating(value)">
<IconStarFilled v-if="value <= rating" color="gold" />
<IconStar v-else color="gray" />
</button>
</template>
</div>
<!-- Conditional icon rendering -->
<component
:is="isCompleted ? IconCheckCircleFilled : IconCheckCircle"
:color="isCompleted ? 'green' : 'gray'"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import {
IconHeart,
IconHeartFilled,
IconStar,
IconStarFilled,
IconCheckCircle,
IconCheckCircleFilled
} from '@tabler/icons-vue';
const isFavorite = ref(false);
const rating = ref(0);
const isCompleted = ref(false);
const toggleFavorite = () => {
isFavorite.value = !isFavorite.value;
};
const setRating = (value) => {
rating.value = value;
};
</script>Deep integration with Vue 3's Composition API for reactive icon properties and dynamic behavior.
/**
* Vue 3 Composition API integration patterns
* Icons work seamlessly with refs, computed properties, and watchers
*/
// Reactive icon properties
import { ref, computed, watch } from 'vue';
// Example composable for icon theme
function useIconTheme() {
const isDark = ref(false);
const iconColor = computed(() => isDark.value ? '#ffffff' : '#000000');
const iconSize = computed(() => isDark.value ? 28 : 24);
return { isDark, iconColor, iconSize };
}
// Example composable for icon animation
function useIconAnimation() {
const isAnimating = ref(false);
const rotation = ref(0);
const startAnimation = () => {
isAnimating.value = true;
rotation.value += 360;
};
return { isAnimating, rotation, startAnimation };
}Usage Examples:
<template>
<div>
<!-- Theme-aware icons -->
<IconSun
v-if="!isDark"
:color="iconColor"
:size="iconSize"
@click="toggleTheme"
/>
<IconMoon
v-else
:color="iconColor"
:size="iconSize"
@click="toggleTheme"
/>
<!-- Animated loading icon -->
<IconLoader
:style="{
transform: `rotate(${rotation}deg)`,
transition: 'transform 0.5s ease'
}"
:class="{ spinning: isLoading }"
/>
<!-- Status-based icons -->
<IconCheck
v-if="status === 'success'"
color="green"
:size="statusIconSize"
/>
<IconX
v-else-if="status === 'error'"
color="red"
:size="statusIconSize"
/>
<IconClock
v-else
color="gray"
:size="statusIconSize"
/>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
import {
IconSun,
IconMoon,
IconLoader,
IconCheck,
IconX,
IconClock
} from '@tabler/icons-vue';
// Theme composable
const isDark = ref(false);
const iconColor = computed(() => isDark.value ? '#ffffff' : '#000000');
const iconSize = computed(() => isDark.value ? 28 : 24);
const toggleTheme = () => {
isDark.value = !isDark.value;
};
// Animation state
const isLoading = ref(false);
const rotation = ref(0);
watch(isLoading, (loading) => {
if (loading) {
const interval = setInterval(() => {
rotation.value += 90;
}, 200);
// Cleanup on stop loading
watch(() => !loading, () => clearInterval(interval), { once: true });
}
});
// Status management
const status = ref('pending'); // 'success' | 'error' | 'pending'
const statusIconSize = computed(() => {
return status.value === 'success' ? 32 : 24;
});
</script>
<style scoped>
.spinning {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>Common patterns for using icons within Vue templates with directives and computed properties.
/**
* Vue template integration patterns
* Advanced usage with v-model, v-for, v-if, and other directives
*/
// Dynamic icon selection
interface IconConfig {
name: string;
component: any;
props?: Record<string, any>;
}
// Icon registry for dynamic rendering
const iconRegistry = {
home: IconHome,
user: IconUser,
settings: IconSettings,
// ... more icons
};Usage Examples:
<template>
<div>
<!-- Dynamic icon rendering with v-for -->
<div class="icon-grid">
<div
v-for="icon in icons"
:key="icon.name"
class="icon-card"
@click="selectIcon(icon)"
>
<component
:is="icon.component"
:size="icon.size || 24"
:color="icon.color || 'currentColor'"
/>
<span>{{ icon.name }}</span>
</div>
</div>
<!-- Conditional icon rendering -->
<div class="status-indicator">
<IconCheck v-if="isValid" color="green" />
<IconX v-else-if="hasError" color="red" />
<IconLoader v-else class="spinning" />
</div>
<!-- Icon with v-model integration -->
<div class="rating-input">
<template v-for="star in 5" :key="star">
<IconStarFilled
v-if="star <= rating"
color="gold"
@click="rating = star"
/>
<IconStar
v-else
color="gray"
@click="rating = star"
/>
</template>
</div>
<!-- Icon button with slot content -->
<button class="icon-button" @click="handleAction">
<IconPlus size="16" />
<span>{{ buttonText }}</span>
</button>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import {
IconHome,
IconUser,
IconSettings,
IconCheck,
IconX,
IconLoader,
IconStar,
IconStarFilled,
IconPlus
} from '@tabler/icons-vue';
// Dynamic icons
const icons = ref([
{ name: 'Home', component: IconHome, size: 32 },
{ name: 'User', component: IconUser, color: '#3b82f6' },
{ name: 'Settings', component: IconSettings },
]);
const selectIcon = (icon) => {
console.log('Selected:', icon.name);
};
// Status management
const isValid = ref(false);
const hasError = ref(false);
// Rating with v-model
const rating = ref(0);
// Button state
const buttonText = computed(() =>
rating.value > 0 ? 'Update Rating' : 'Add Rating'
);
const handleAction = () => {
console.log('Action triggered with rating:', rating.value);
};
</script>
<style scoped>
.icon-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 1rem;
}
.icon-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 1rem;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
cursor: pointer;
transition: background-color 0.2s;
}
.icon-card:hover {
background-color: #f9fafb;
}
.status-indicator {
display: flex;
align-items: center;
gap: 0.5rem;
}
.rating-input {
display: flex;
gap: 0.25rem;
}
.rating-input svg {
cursor: pointer;
transition: transform 0.1s;
}
.rating-input svg:hover {
transform: scale(1.1);
}
.icon-button {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
background-color: #3b82f6;
color: white;
cursor: pointer;
transition: background-color 0.2s;
}
.icon-button:hover {
background-color: #2563eb;
}
.spinning {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>Create reusable composables for common icon functionality and state management.
<script setup>
import { ref, computed } from 'vue';
import { IconHeart, IconHeartFilled } from '@tabler/icons-vue';
// Favorite toggle composable
function useFavorite(initialState = false) {
const isFavorite = ref(initialState);
const toggleFavorite = () => {
isFavorite.value = !isFavorite.value;
};
const FavoriteIcon = computed(() =>
isFavorite.value ? IconHeartFilled : IconHeart
);
const favoriteProps = computed(() => ({
color: isFavorite.value ? 'red' : 'gray',
size: 20
}));
return {
isFavorite,
toggleFavorite,
FavoriteIcon,
favoriteProps
};
}
// Usage
const { isFavorite, toggleFavorite, FavoriteIcon, favoriteProps } = useFavorite();
</script>
<template>
<button @click="toggleFavorite">
<component :is="FavoriteIcon" v-bind="favoriteProps" />
{{ isFavorite ? 'Favorited' : 'Favorite' }}
</button>
</template>Create icon provider components for consistent theming and configuration.
<!-- IconProvider.vue -->
<template>
<div class="icon-provider" :class="themeClass">
<slot :iconProps="iconProps" :theme="theme" />
</div>
</template>
<script setup>
import { computed, provide } from 'vue';
const props = defineProps({
theme: {
type: String,
default: 'light'
},
size: {
type: [String, Number],
default: 24
},
strokeWidth: {
type: [String, Number],
default: 2
}
});
const themeClass = computed(() => `icon-theme-${props.theme}`);
const iconProps = computed(() => ({
size: props.size,
strokeWidth: props.strokeWidth,
color: props.theme === 'dark' ? '#ffffff' : '#000000'
}));
// Provide theme context
provide('iconTheme', {
theme: props.theme,
iconProps: iconProps.value
});
</script>
<style scoped>
.icon-theme-dark {
background-color: #1f2937;
color: #ffffff;
}
.icon-theme-light {
background-color: #ffffff;
color: #000000;
}
</style>Best practices for optimizing icon performance in Vue applications.
<script setup>
import { ref, shallowRef, defineAsyncComponent } from 'vue';
// Lazy load icons for better performance
const LazyIconHome = defineAsyncComponent(() =>
import('@tabler/icons-vue').then(mod => ({ default: mod.IconHome }))
);
// Icon registry with lazy loading
const iconComponents = shallowRef({});
const loadIcon = async (iconName) => {
if (!iconComponents.value[iconName]) {
const module = await import('@tabler/icons-vue');
iconComponents.value[iconName] = module[iconName];
}
return iconComponents.value[iconName];
};
// Preload commonly used icons
const preloadIcons = async () => {
const commonIcons = ['IconHome', 'IconUser', 'IconSettings'];
await Promise.all(commonIcons.map(loadIcon));
};
// Call on component mount
preloadIcons();
</script>
<template>
<div>
<!-- Lazy loaded icon -->
<Suspense>
<LazyIconHome />
<template #fallback>
<div class="icon-placeholder" />
</template>
</Suspense>
<!-- Dynamic icon loading -->
<component
v-if="iconComponents[selectedIcon]"
:is="iconComponents[selectedIcon]"
v-bind="iconProps"
/>
</div>
</template>Install with Tessl CLI
npx tessl i tessl/npm-tabler--icons