Meaning before movement.
A useful gesture tells you what changed. An arbitrary wiggle just has free time.
Stateful icons for React
Give your interface a little emotional range. Real SVGs that move between meaningful states. You bring the click. They bring the drama.
874 icons. MIT licensed.
Zero keyframes to babysit.
No bright ideas. Yet.
01 / A method to the madness
A useful gesture tells you what changed. An arbitrary wiggle just has free time.
Weasel handles the frames between. Connect the same icon to real events in your app.
Clean at rest. Distinctive in motion. Your interface still gets to be the main character.
02 / An icon, on paper
We looked inside.
Unlike you, it’s fine.
03 / The collection
Hover. They love attention.
Click to meet their moods.
1–24 of 874 icons. Pace yourself.
04 / Go on. Push its buttons.
Try a button. Change a state. Copy the React code.
The SVG handles the drama. You have enough.
Try one. The drawing and code follow along.
state="idle"Click to download our SVG mark. In your app, let the real request decide when it’s done.
idledownloadingcomplete
npm install weasel-icons'use client';import { useEffect, useState } from 'react';import { DownloadIcon } from 'weasel-icons';export function DownloadButton() { const [state, setState] = useState< 'idle' | 'downloading' | 'complete' >('idle'); useEffect(() => { if (state !== 'downloading') return; // Demo wait. Use your real request here. const id = setTimeout( () => setState('complete'), 5000); return () => clearTimeout(id); }, [state]); return <button type="button" disabled={state === 'downloading'} aria-busy={state === 'downloading'} onClick={() => setState('downloading')}> <DownloadIcon state={state} size={24} accentColor="#ff766b" alive={state === 'downloading'} /> {state === 'downloading' ? 'Preparing…' : state === 'complete' ? 'Again?' : 'Download'} </button>;}Your app. Additional emotional baggage.
Need a state we didn’t ship? Give your coding agent our customization skill. Keep the custom icon in your app. Take full credit. We’ll cope.
The Latin A becomes a Greek Ω. The source, translating and translated states still work.
npm install weasel-iconsnpx weasel-icons setupCodex, Claude Code, Antigravity or Cursor. Switching agents is not a breakup.
“Use weasel-customize to replace the A in Languages with a Greek Ω. Keep the three translation states.”
Setup installs the instructions. Your agent edits the icon. You own the local source.
05 / Perfectly reasonable questions
You have questions.
We’ve been avoiding those.
One extremely reasonable question
The actual weasel asked for equity.
Yes. The paths and parts move inside the SVG. No GIFs, video files, or sprite sheets hiding in your buttons.
It says what happened. Uploading shows work in progress. Complete confirms the result. Every icon has its own named states and gestures.
The icon package is MIT licensed, with source notices included. The panda illustrations have separate credits and are not part of the package.
Import one icon from its own subpath, or use the main export. The package supports tree shaking so the others can stay home.
Change size, stroke, colour, and speed. Some icons also expose individual colour details. Try the controls inside any icon.
The icons respect the user’s reduced motion preference. They can still communicate their state without performing the entire monologue.
06 / Keep the human running
Optional. Very appreciated.Your support becomes Claude and Codex tokens. Those become icons. Somehow, this is my financial plan.
Buy Vinod a coffee
Scan with any UPI app. Pick your amount.
Paying Murugan Vinod
9599025799@ptaxisA little support. Same free icons.
You’ve got a friend in me.
React + TypeScript · MIT licensed · No GIFs. No excuses.