Icons

ubean provides two icon systems that serve different purposes:

1. @ubean/icon (Built-in Icon System)

@ubean/icon is ubean’s built-in icon plugin that provides Iconify integration at build time and runtime. It handles icon collection scanning, SVG generation, and runtime icon rendering.

Features

  • Iconify icon set support (100k+ icons from multiple collections)
  • SVG and CSS rendering modes
  • Vite plugin for SFC icon scanning and preloading
  • Custom icon collection registration (object-shape config)
  • Runtime icon loading with API fallback (/_iconify dev route)
  • Tree-shakeable icons
  • Flip/rotate transforms

Installation & Configuration

@ubean/icon is a built-in module that is disabled by default. Enable it via ubean.config.ts:

// ubean.config.ts
import { defineConfig } from 'ubean';

export default defineConfig({
  icon: true // Enable built-in icon system with defaults
});

Enable with Custom Options

The icon config field accepts true (defaults) or an options object — object fields (e.g. customCollections) are passed through to the ubeanIconPlugin Vite plugin (@ubean/icon/vite); only the module-system disabled flag is stripped:

// vite.config.ts
import { defineConfig } from 'vite';
import { ubeanIconPlugin } from '@ubean/icon/vite';

export default defineConfig({
  plugins: [
    ubeanIconPlugin({
      collections: {
        mdi: () => import('@iconify-json/mdi').then(m => m.icons) // lazy collection
      },
      customCollections: {
        brand: './src/icons/brand'
      },
      fallbackToApi: true,      // fetch missing icons from the Iconify API
      iconifyApiEnabled: true   // master switch for the API fallback
    })
  ]
});
OptionTypeDescription
collectionsRecord<string, IconifyCollection | (() => Promise<IconifyCollection>)>Iconify collections to register
customCollectionsRecord<string, string | { dir, prefix?, normalizeIconName? }>Local SVG directory collections (object form)
fallbackToApibooleanFetch missing icons from the Iconify API (default true)
iconifyApiEnabledbooleanMaster switch for API fallback (default true)
iconApiEndpointstringIconify API base URL (default https://api.iconify.design)
ssrbooleanEnable server-side SVG rendering (default true)
cssSelectorPrefixstringCSS-mode class prefix (default 'i-')
cssWherePseudobooleanScope CSS rules with :where() (default true)

Custom collections

customCollections accepts an object-shape config (not an array). Each key maps to either a directory shorthand or a full { dir, prefix, normalizeIconName } object. Nested subdirs are flattened into hyphenated prefixes.

import { defineConfig } from 'ubean';

export default defineConfig({
  icon: {
    customCollections: {
      brand: './src/icons/brand',           // shorthand
      ui: {
        dir: './src/icons/ui',
        prefix: 'ui',
        normalizeIconName: (name: string) => name.toLowerCase()
      }
    }
  }
});

Basic Usage (Icon component)

The component is exported as Icon (its internal component name is UbeanIcon):

<script setup lang="ts">
import { Icon } from '@ubean/icon';
</script>

<template>
  <!-- Basic usage -->
  <Icon name="mdi:home" />

  <!-- With size and color -->
  <Icon name="mdi:user" :size="24" color="#42b883" />

  <!-- CSS mode -->
  <Icon name="mdi:settings" mode="css" />

  <!-- Flip and rotate -->
  <Icon name="mdi:arrow-right" flip="horizontal" />
  <Icon name="mdi:refresh" rotate="90" />
</template>

Icon Props (UbeanIcon)

PropTypeDefaultDescription
namestringrequiredIcon name in collection:icon format
sizenumber | string‘1em’Icon size (px number or CSS value)
colorstringundefinedIcon color (CSS color)
classNamestring‘’Additional CSS class
ariaLabelstringundefinedARIA label for accessibility
titlestringundefinedHover title
mode‘svg’ | ‘css’‘svg’Rendering mode
flip‘horizontal’ | ‘vertical’ | ‘both’undefinedFlip direction
rotatenumber | stringundefinedRotation degrees
inlinebooleanfalseInline display alignment

Register Custom Icon Collections at Runtime

import { defineIconCollection, defineIconCollectionLoader } from '@ubean/icon';

// Static collection
defineIconCollection({
  prefix: 'custom',
  icons: {
    logo: {
      body: '<path d="M12 2L2 7l10 5 10-5-10-5z" />',
      width: 24,
      height: 24
    }
  }
});

// Lazy-loaded collection
defineIconCollectionLoader('my-icons', async () => {
  return (await import('/icons/my-icons.json')).default;
});

Programmatic API

import { useIcon, getIconSync, getIcon, addIconCollection } from '@ubean/icon';

// useIcon composable
const icon = useIcon('mdi:home');
const svg = await icon.getSvg();
const svgSync = icon.getSvgSync();

// Direct functions
const iconData = getIconSync('mdi:home');
const iconDataAsync = await getIcon('mdi:home');

Local SVG serving (dev)

When iconifyApiEnabled and fallbackToApi are both on, a /_iconify dev route serves SVGs locally first (from custom collections), falling back to the Iconify API for anything else. parseSvgToIconData() extracts body + width/height/viewBox from raw SVG files.


2. @vean/ui SIcon Component

SIcon is a UI component from @vean/ui that provides a styled icon component integrated with VeanUI’s design system, theming, and styling conventions.

Features

  • Integrated with @vean/ui theme system (light/dark mode, theme colors)
  • Consistent sizing with UI components (xs/sm/md/lg/xl presets)
  • Styled with shadcn-ui design system conventions
  • Works with SConfigProvider for global size/theme configuration
  • Supports all Iconify icons

When to Use SIcon

Use SIcon when:

  • You are building UI with @vean/ui components
  • You need consistent theming with your application’s design system
  • You want preset sizes that match VeanUI components
  • You’re using SButton, SCard, etc. and need matching icon styles

Installation

pnpm add @vean/ui

Configuration (with unplugin-vue-components)

// vite.config.ts
import Components from 'unplugin-vue-components/vite';
import { UiResolver } from '@vean/ui/resolver';

export default defineConfig({
  plugins: [
    Components({
      resolvers: [UiResolver()]
    })
  ]
});

Theme Configuration

<script setup lang="ts">
import { SConfigProvider } from '@vean/ui';
</script>

<template>
  <SConfigProvider
    theme="light"
    :theme-config="{
      colors: { primary: '#42b883' },
      size: 'default'
    }"
  >
    <App />
  </SConfigProvider>
</template>

Basic Usage (SIcon)

<script setup lang="ts">
import { SIcon } from '@vean/ui';
</script>

<template>
  <!-- Basic usage -->
  <SIcon icon="mdi:home" />

  <!-- With preset sizes -->
  <SIcon icon="mdi:user" size="sm" />
  <SIcon icon="mdi:settings" size="lg" />

  <!-- With custom size -->
  <SIcon icon="mdi:bell" :size="24" />

  <!-- With theme colors -->
  <SIcon icon="mdi:check" color="success" />
  <SIcon icon="mdi:alert" color="error" />
  <SIcon icon="mdi:info" color="primary" />

  <!-- In buttons -->
  <SButton>
    <SIcon icon="mdi:plus" class="mr-2" />
    Add Item
  </SButton>
</template>

SIcon Props

PropTypeDefaultDescription
iconstringrequiredIcon name (Iconify format: collection:icon)
size‘xs’ | ‘sm’ | ‘md’ | ‘lg’ | ‘xl’ | number‘md’Icon size (preset or px)
colorstringundefinedTheme color token or CSS color
spinbooleanfalseSpinning animation
classstring‘’Additional CSS class

Key Differences

Feature@ubean/icon (UbeanIcon)@vean/ui (SIcon)
Component<Icon> (internal name UbeanIcon)<SIcon>
Icon propname (e.g. name="mdi:home")icon (e.g. icon="mdi:home")
PurposeBuild-time + runtime icon engineUI-styled icon component
DependenciesNone (built-in module, opt-in via icon: true)Requires @vean/ui
ThemingRaw CSS color supportIntegrated with VeanUI theme tokens
Size formatCSS values/px numbersxs/sm/md/lg/xl presets + numbers
Rendering modesSVG and CSS modesSVG only (styled)
TransformsBuilt-in flip/rotate propsCSS transforms via class/style
API accessFull programmatic API (useIcon, getIcon, etc.)Component-only
Tree-shakingVite SFC scanning + preloadingDepends on unplugin-vue-components
Custom collectionsdefineIconCollection / defineIconCollectionLoaderDepends on @ubean/icon runtime

Recommendation

  • Use Icon for general icon needs, custom icon collections, server-side icon generation, or when not using @vean/ui
  • Use SIcon when building UI with @vean/ui components for consistent theming and styling across your application
  • Both systems use the same Iconify icon naming (collection:icon format)
  • You can use both in the same project if needed: Icon for infrastructure/non-UI icons, SIcon for UI components

Icon Collections

Popular Iconify Collections

CollectionPrefixExample
Material Design Iconsmdimdi:home, mdi:menu, mdi:settings
Font Awesomefafa:user, fa:home, fa:github
Simple Iconssimple-iconssimple-icons:vuejs, simple-icons:react
Tabler Iconstablertabler:home, tabler:user, tabler:settings
Lucide Iconslucidelucide:home, lucide:search, lucide:menu
Carbon Iconscarboncarbon:home, carbon:user-avatar
Bootstrap Iconsbibi:house, bi:person
Heroiconsheroiconsheroicons:home, heroicons:user

Best Practices

  1. Choose one primary system: Prefer SIcon for UI, Icon for framework features
  2. Use consistent size: Align icon sizes with your design system
  3. Accessibility: Always provide ariaLabel for meaningful icons
  4. Preload critical icons: Configure collections in the ubeanIconPlugin options for frequently used sets
  5. Custom SVGs: Use custom collections for brand-specific icons
  6. Performance: Leverage tree-shaking and avoid loading unnecessary collections