Icon
Renders a single icon from any of the forms accepted library-wide (P11): a lucide-* string, an emoji/symbol string, or a Vue component. Most components take an icon prop directly and render it through Icon internally — reach for Icon yourself only when you need an icon outside of one of those props.
Lucide string
vue
<script setup lang="ts">
import { Icon } from 'frappe-ui'
</script>
<template>
<div class="flex items-center gap-4 text-ink-gray-8">
<Icon name="lucide-plus" class="size-5" />
<Icon name="lucide-trash-2" class="size-5" />
<Icon name="lucide-check" class="size-5" />
<Icon name="🎉" class="text-xl" />
</div>
</template>Component
vue
<script setup lang="ts">
import { h } from 'vue'
import { Icon } from 'frappe-ui'
// The escape hatch: pass any Vue component as the icon source.
const CustomIcon = () =>
h(
'svg',
{ viewBox: '0 0 24 24', fill: 'none', class: 'size-5' },
[
h('circle', {
cx: 12,
cy: 12,
r: 9,
stroke: 'currentColor',
'stroke-width': 2,
}),
],
)
</script>
<template>
<Icon :name="CustomIcon" class="text-ink-gray-8" />
</template>API Reference
Show types
typescript
import type { Component } from 'vue'
export interface IconProps {
/**
* Icon source. Supported forms:
* - `lucide-*` string → rendered via the Tailwind mask plugin.
* - emoji / symbol string → rendered as plain text.
* - Vue component → rendered via `<component :is>`.
* Any other string (e.g. a bare feather-style name) is unsupported —
* it renders nothing and warns once in dev. Falsy values render nothing.
*/
name?: string | Component | null
}name
string | Component | null
Icon source. Supported forms: - `lucide-*` string → rendered via the Tailwind mask plugin. - emoji / symbol string → rendered as plain text. - Vue component → rendered via `<component :is>`. Any other string (e.g. a bare feather-style name) is unsupported — it renders nothing and warns once in dev. Falsy values render nothing.