# Wobnimo
> Twenty animated mascots on one featherweight web animation engine (~25.2 KB gzipped, zero dependencies). Drop-in web component, first-class React wrapper, and agent-ready. Use it to give an app or AI assistant a face that reacts to what it is doing.
## Install
One tag, no build step:
```html
```
With a bundler: `npm i wobnimo`
- React/Next: `import { Mascot } from 'wobnimo/react'` then `` (add "use client" in Next app-router files).
- Anywhere else: `import 'wobnimo/element'` then ``.
- In code: `import { mount } from 'wobnimo'`; `import { mochi } from 'wobnimo/characters/mochi'`; `mount(el, mochi).setState('thinking')`.
Import one character (~1.2 KB each) from `wobnimo/characters/`, or the whole cast from `wobnimo/characters`.
## AI chat, one prop
With the Vercel AI SDK, pass the useChat `status` straight in; the mascot thinks, speaks, celebrates and errors for you:
```tsx
const { status } = useChat();
```
With the element, set the `status` attribute to submitted | streaming | ready | error.
## Characters
- volt (Volt): LED face, claw hands, gear ears, a sprung antenna
- pip (Pip): Sings with a real beak, snaps its head like a bird, flaps
- mochi (Mochi): Translucent jelly that squashes and splashes, with a propeller sprout
- boo (Boo): Floats, glows from inside, trails motes, a hem that ripples
- inky (Inky): Floats, with six tentacles that trail on spring chains
- miso (Miso): A plush tabby with velvet fur, swivelling ears and a tail that never sits still
- tad (Tad): A glossy tree frog with a wet sheen, eyes on top and a throat that puffs as it talks
- pebble (Pebble): A penguin chick in a knitted scarf: satin coat, waddling walk, flippers that flap when it is happy
- rex (Rex): A baby T. rex with pebbly scales, wobbly back spikes, tiny arms and a wagging tail
- microduck (Microduck): A bipedal robot duck: servo neck, lens eyes, a bill that clacks when it talks, and boots it marches in
- drift (Drift): A sleepy blue cloud that floats along to the music in its headphones
- cacti (Cacti): A tiny potted cactus with a pink flower that bounces on its head
- latte (Latte): A cheerful coffee cup with latte-art foam and a curl of steam for hair
- bumble (Bumble): A fuzzy round bumblebee that hovers on wings far too small for it
- swirl (Swirl): A slow, sweet snail carrying a glazed cinnamon roll for a shell
- ember (Ember): A fox cub with pointed ears and a big fluffy tail that never stops swishing
- cap (Cap): A little toadstool with a glossy red cap that wobbles when it walks
- berry (Berry): A plump strawberry with golden seeds and a leafy hat with a stalk on top
- bao (Bao): A chubby panda cub: round ears, eye patches, and a belly made for sitting
- hop (Hop): A soft white bunny whose long floppy ears swing with every hop
## States (set via the state prop/attribute or mascot.setState)
- idle: waiting for the user
- thinking: a request is sent, no reply yet
- listening: the user is typing or talking
- speaking: a reply is streaming in
- sleeping: idle for a couple of minutes
- working: running a tool, a build or a long task
- error: something failed
- surprised: an unexpected event
- celebrating: a task finished, tests passed
- sad: it could not help
## Make your own character
A character is one TypeScript file exporting a CharacterSpec (plain data: materials, bones, SDF parts, paints, eyes, face, anchors, acting). To have an agent design one from a sentence:
1. `npx wobnimo skill` adds the wobnimo-mascot skill to .claude/skills and .agents/skills (or `npx skills add Pouryaak/wobnimo`). Read its SKILL.md and follow it.
2. `npx wobnimo new ` writes mascots/.ts, a starter that passes every check.
3. `npx wobnimo check ` measures the real 3D shape and lists errors and warnings, each with the exact fix. Repeat until clean.
4. `npx wobnimo preview ` renders a contact sheet PNG (front, side, back, face close-up, every state, a 56px avatar); `--live` opens a preview that reloads on save.
5. Use it: ``, `element.spec = mySpec`, or `mount(el, mySpec)`.
Skill source: https://github.com/Pouryaak/wobnimo/tree/main/skills/wobnimo-mascot
## Customize
- Recolour by material name: `palette={{ shell: '#e0457b' }}` (React) or `palette="shell:#e0457b"` (attribute). Material names are per character.
- Make a variant or a new character from data with `variant()` and `defineCharacter()` from `wobnimo`.
- Draw a still (avatar, thumbnail) with `snapshot(spec, { state, size })`.
## Notes
- Unknown character or state names throw at runtime and list the valid ones.
- Honours prefers-reduced-motion, sleeps off-screen, shares one WebGL2 context across all mascots on a page.
- Live demo and copy-paste install: https://pouryaak.github.io/wobnimo/