Lucide Icons for Vue 3
lucide-vue-next is the official Vue 3 implementation of Lucide, a modern, community-driven icon library that serves as a spiritual successor to Feather Icons. It provides a highly customizable and extensive collection of SVG icons specifically designed for Vue 3 applications. The library is currently stable at version 1.8.0, with frequent minor and patch releases to add new icons and address bug fixes. Key differentiators include its focus on customizability (stroke width, color, size), its tree-shakeable nature, and a large, ever-growing icon set, ensuring minimal bundle size and flexibility for developers. It leverages Vue's component system for efficient rendering and integration.
Common errors
-
Failed to resolve component: <IconName>
cause The icon component was not imported or was imported with the wrong name/path.fixEnsure you have `import { IconName } from 'lucide-vue-next';` at the top of your script and that `IconName` matches the PascalCase name of the icon you intend to use. -
Uncaught ReferenceError: module is not defined (when using CommonJS)
cause lucide-vue-next is an ESM-first package. Attempting to `require()` it directly in a CommonJS environment without proper transpilation or configuration will fail.fixUse ESM `import` statements. If you are in a Node.js CommonJS environment, you might need to configure your bundler (e.g., Webpack) to handle ESM or use dynamic `import()` if supported. -
[Vue warn]: Component provided is not a function or an object: 'object'
cause This can occur if an icon is imported with a default import, but it is a named export.fixUse named imports for all icons: `import { IconName } from 'lucide-vue-next';` instead of `import IconName from 'lucide-vue-next';`.
Warnings
- gotcha Lucide icons are pure SVG. If you apply CSS styles globally that target `svg` elements, it may unintentionally affect Lucide icons' appearance (e.g., fill, stroke).
- gotcha Ensure proper tree-shaking is configured in your build setup (e.g., Vite or Webpack) to only bundle the icons you actually use. While Lucide is designed to be tree-shakeable, incorrect configurations can lead to larger bundle sizes.
- gotcha Icon names are PascalCase in imports (e.g., `Activity`, `Bell`) but correspond to kebab-case on the Lucide website (e.g., `activity`, `bell`). Ensure you use the correct casing for imports.
Install
-
npm install lucide-vue-next -
yarn add lucide-vue-next -
pnpm add lucide-vue-next
Imports
- Activity
import Activity from 'lucide-vue-next'; // Or const Activity = require('lucide-vue-next').Activity;import { Activity } from 'lucide-vue-next'; - Bell
import { BellIcon } from 'lucide-vue-next'; // Or import * as LucideIcons from 'lucide-vue-next';import { Bell } from 'lucide-vue-next'; - Component usage
<template> <Settings :size="24" color="red" stroke-width="2" /> </template> <script setup> import { Settings } from 'lucide-vue-next'; </script>
Quickstart
<template>
<div class="icon-display">
<h1>Lucide Vue Icons</h1>
<div class="icons-grid">
<Activity :size="48" color="var(--activity-color, #1e90ff)" stroke-width="1.5" />
<BatteryCharging :size="48" color="green" stroke-width="2" />
<Bell :size="48" :color="dynamicColor" stroke-width="2.5" />
<Camera :size="48" color="purple" stroke-width="1" />
</div>
<button @click="toggleColor">Change Bell Color</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Activity, BatteryCharging, Bell, Camera } from 'lucide-vue-next';
const dynamicColor = ref('orange');
function toggleColor() {
dynamicColor.value = dynamicColor.value === 'orange' ? 'blue' : 'orange';
}
</script>
<style scoped>
.icon-display {
font-family: sans-serif;
text-align: center;
padding: 20px;
}
.icons-grid {
display: flex;
gap: 20px;
justify-content: center;
margin-top: 30px;
margin-bottom: 20px;
}
</style>