Skip to content

Icons ​

Klean Icons includes 98 original SVGs for common application actions and objects. Every mark uses the same 24px canvas, calm 1.5px stroke, rounded joins, and optical rhythm.

Search is reflected in the page URL, so a filtered catalog can be reloaded, bookmarked, and shared. The catalog remembers your framework choice.

Installation ​

Install one icon by its lowercase name. The CLI detects Vue, React, or Svelte and writes the matching source into the conventional icons directory:

Run from your application’s directory. Klean detects your framework and copies the matching source.

Terminal
npx klean-ui add icon trash

Source you own. Edit the installed files to make them yours.

Install several icons in one command when a screen needs a set:

Terminal
npx klean-ui add icon trash search calendar

Re-running add preserves changed local source. Use klean-ui check icon trash, diff icon trash, or update icon trash when you deliberately review upstream changes.

Usage ​

The component is decorative by default. Put its meaning in visible button or link text, or in the accessible name of the semantic parent control.

vue
<script setup>
import Trash from '@/components/ui/icons/Trash.vue'
</script>

<template>
  <button
    type="button"
    class="inline-flex items-center gap-2 rounded-lg bg-red-600 px-3 py-2 text-sm font-semibold text-white"
    aria-label="Delete invoice"
  >
    <Trash class="size-4" />
    Delete
  </button>
</template>
jsx
import Trash from '@/components/ui/icons/Trash.jsx'

export default function DeleteInvoice() {
  return (
    <button
      type="button"
      className="inline-flex items-center gap-2 rounded-lg bg-red-600 px-3 py-2 text-sm font-semibold text-white"
      aria-label="Delete invoice"
    >
      <Trash className="size-4" />
      Delete
    </button>
  )
}
svelte
<script>
  import Trash from '$lib/components/ui/icons/Trash.svelte'
</script>

<button
  type="button"
  class="inline-flex items-center gap-2 rounded-lg bg-red-600 px-3 py-2 text-sm font-semibold text-white"
  aria-label="Delete invoice"
>
  <Trash class="size-4" />
  Delete
</button>

Styling ​

Icons use 1em for width and height and currentColor for stroke. Text size and color utilities therefore work without a Klean-specific API:

vue
<Search class="size-5 text-blue-600" />
<Bell class="size-4 text-gray-500" stroke-width="1.75" />
<Rocket class="size-8 text-orange-500" />

Use size-*, text-*, opacity, responsive, state, and dark-mode utilities directly. Native SVG attributes such as stroke-width, aria-label, and role are forwarded by every framework component.

Do not make every icon louder to create hierarchy. Start with one color and one stroke weight. Let placement, visible text, and the parent control carry most of the meaning.

API ​

InputDefaultPurpose
class / className—Ordinary Tailwind sizing, color, opacity, state, responsive, and dark-mode utilities.
stroke-width / strokeWidth1.5Native SVG stroke override for a deliberate product treatment.
other SVG attributesnativeIDs, data hooks, event handlers, roles, labels, and other framework-native SVG inputs.
element reference—Framework-native access to the SVG element when genuinely needed.
accessible presentationdecorativeHidden from assistive technology by default; override only for a truly informative mark.

Accessibility ​

Prefer visible text. In a button that says “Delete”, Trash is decorative and should stay hidden from assistive technology. For an icon-only control, name the button—not the SVG:

vue
<button type="button" aria-label="Delete invoice">
  <Trash class="size-5" />
</button>

Only make the SVG itself informative when it stands alone and no semantic parent can own its name:

vue
<CheckCircle
  class="size-5 text-emerald-600"
  role="img"
  aria-hidden="false"
  aria-label="Payment complete"
/>
  • Never rely on the icon alone when a destructive, irreversible, unfamiliar, or status-changing action needs text.
  • Keep touch and pointer targets on the parent Button or link at least 44px; enlarging the SVG does not enlarge the target.
  • Do not encode status with color alone. Pair the mark with useful text.
  • Avoid redundant names such as a labeled button containing a separately labeled icon.
  • Icons are not focusable. Keyboard focus belongs to the control that owns the action.

Why source-owned icons ​

You can inspect and edit each installed icon's SVG geometry in your application.

The shared 24px geometry keeps icons consistent. Use currentColor, native attributes, and Tailwind classes to match your application's density, palette, contrast, and motion.

Updates are deliberate. Klean never silently replaces local geometry. The CLI shows whether an installed icon differs, and the application chooses when to inspect and accept a new source version.

Naming ​

Use the concrete object or action: Trash, Search, Calendar, Copy. Do not encode placement, product, color, or size into the exported name. The same Bell can appear in a header, notification preference, or activity feed without becoming three components.

The CLI uses lowercase kebab-case names while framework exports use PascalCase:

sh
npx klean-ui add icon check-circle chevron-right
js
import CheckCircle from '@/components/ui/icons/CheckCircle.vue'
import ChevronRight from '@/components/ui/icons/ChevronRight.vue'

When to use ​

Use Klean Icons for repeated application actions, navigation, statuses, dates, identity, infrastructure, notifications, and deployment language. Use the shared source when consistency is more valuable than a product-specific illustration.

When not to use ​

  • Use text without an icon when the mark adds no recognition or scanning value.
  • Use a logo or product mark for brand identity; do not force a general interface icon to become one.
  • Use an illustration for editorial, empty-state, onboarding, or marketing storytelling.
  • Use Spinner for indeterminate progress and Avatar for resilient identity images.
  • Keep specialized domain icons alongside the application code that uses them.
  • Button — owns action semantics, target size, pending state, and accessible naming around an icon.
  • Menu, Command, and Tabs — compose icons with truthful actions, destinations, and navigation.
  • Tooltip — adds brief supplementary text to a real icon-only control; it does not replace the control's accessible name.
  • Badge, Alert, and Toast — pair status marks with visible language and truthful announcement behavior.
  • Avatar, Spinner, and Empty State — cover nearby visual roles that should not be folded into the icon contract.

All open source projects are released under the MIT License.