Skip to content
Kineticons

Start

React

Use Kineticons in React: named icon components, the KineticIcon component, props, Server Components and tree-shaking.

Install

shell
npm install kineticons

Works with React 18 and 19, Vite, Next.js, Remix and anything that bundles ES modules.

Usage

Every icon is a component named after it in PascalCase: bell is Bell, arrow-right is ArrowRight. Each also has an …Icon alias (BellIcon) for when the plain name clashes with your own.

tsx
import { ArrowRight, Bell, Trash } from "kineticons";

<button className="ki-trigger">
  <Trash variant="filled" size={18} />
  Delete
</button>

<a href="/next" className="ki-trigger">
  Continue <ArrowRight size={16} strokeWidth={2} />
</a>

Props

Every icon component takes these, plus any SVG attribute (className, style, aria-*, event handlers), and forwards its ref to the <svg>.

PropTypeDefaultWhat it does
variant"outline" | "duotone" | "filled""outline"The style.
sizenumber | string24Width and height, in pixels (or any CSS length as a string).
strokeWidthnumber1.75Stroke in 24-grid units; the same visual weight at any size.
trigger"hover" | "manual" | "loop" | "none""hover"When the icon moves.
activebooleanfalseWith trigger "manual": plays while true.
loopEverynumber1800With trigger "loop": one beat, in milliseconds.
titlestringAn accessible name: the icon is then announced as an image.

Icons chosen at runtime

When the icon comes from data, pass its definition to KineticIcon. Definitions are named in camelCase in kineticons/data; ICONS holds all of them (importing it bundles every icon, so keep that for tools like a picker).

tsx
import { KineticIcon } from "kineticons";
import { bell, mail, trash } from "kineticons/data";

const ACTIONS = { notify: bell, email: mail, remove: trash };

<KineticIcon icon={ACTIONS[action]} variant="duotone" />

Server Components

With React 19, icons render in Server Components with no client JavaScript: each icon’s CSS is hoisted into the page’s head once, however many times it appears. Only trigger="loop" needs the client, and that part is marked for it, so you never write "use client" for an icon.

Bundle size

The package is free of side effects and every icon is its own export, so bundlers keep only the icons you import. A typical icon adds well under 1 KB gzipped, its motion included.

Something unclear or missing? Open an issue.