Start
React
Use Kineticons in React: named icon components, the KineticIcon component, props, Server Components and tree-shaking.
Install
npm install kineticonsWorks 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.
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>.
| Prop | Type | Default | What it does |
|---|---|---|---|
| variant | "outline" | "duotone" | "filled" | "outline" | The style. |
| size | number | string | 24 | Width and height, in pixels (or any CSS length as a string). |
| strokeWidth | number | 1.75 | Stroke in 24-grid units; the same visual weight at any size. |
| trigger | "hover" | "manual" | "loop" | "none" | "hover" | When the icon moves. |
| active | boolean | false | With trigger "manual": plays while true. |
| loopEvery | number | 1800 | With trigger "loop": one beat, in milliseconds. |
| title | string | An 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).
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.