fayazara / robot-heads
git clone https://github.com/fayazara/robot-heads.git
Animated 3D robot heads for React: TV-headed bots with LED faces that show what your agent is doing.
+9
stars, 24h · #3,670
+~40
stars, 7 days · #4,875
+398
stars, 30 days · #2,068
398
★ total · +11% this week
57
forks · 3 open issues
Star history (as recorded here)
LanguageTypeScript
LicenseMIT
Created2026-10-09 (14d ago)
Last push13d ago
Watchers0
OwnerUser
GitHub topics
Links
- GitHub: github.com/fayazara/robot-heads
- Homepage: https://robot-heads.fayaz.workers.dev
- Releases · Issues · Hacker News mentions
README excerpt
# robot-heads
Animated 3D robot heads for React. Glossy, TV-headed bots with an LED-matrix face that shows what your agent is doing — thinking, searching, listening, speaking and more — in four shapes, with a springy antenna, knob ears and a light on top that changes with the state.
Drawn on a 2D canvas: no WebGL, no runtime dependencies.
**Playground →**
## Install
[code]
React 18 or newer is a peer dependency.
## Quick start
[code]
## Shapes
One head, four outlines. Every shape carries the same screen, ears, antenna, screws and back panel, and moves the same way.
[code]
The list is exported as `robotHeadShapes`.
## States
Each state has its own face on the screen, its own motion and its own antenna light. Switching states plays a short glitch and cross-fade, and the head eases into its new pose.
| State | Screen | Motion |
|---|---|---|
| `idle` | block eyes that blink and glance | looks around, hops now and then |
| `thinking` | heavy-lidded eyes looking up, three pulsing dots | head tilted up, switching sides; amber light pulses |
| `searching` | darting eyes, a beam sweeping the whole screen | head sweeps side to side; cyan beacon |
| `listening` | alert eyes over a live equaliser | head cocked, small nods; steady green light |
| `speaking` | a mouth that moves with the words | bobs as it talks |
| `working` | focused eyes looking down, a progress bar | busy bobbing, a hop with a spin now and then |
| `happy` | `^ ^` eyes and a smile | bouncy hops |
| `error` | red `X X` eyes | shakes its head; red light blinks |
| `sleeping` | closed eyes and rising z's | head drooped, slow breathing; light off |
The list is exported as `robotHeadStates`.
## Props
[code]
Any other attribute (`className`, `style`, `onClick`, `aria-label`, …) goes on the element, and a `ref` reaches the ` ` inside it.
## Sizing and layout
`size` is the robot itself: the element is a `size` × `size` box with the robot at rest centred in it, filling it, antenna included. It lines up with text, sits in a flex row, and centres like an icon or an avatar would.
Its motion is not part of that box. Hops, the antenna's glow and the floor's shadow draw past its edges — like a CSS `box-shadow`, they overflow without taking any room in your layout, and only the box takes clicks. So margins, flex and grid treat it as exactly `size` × `size`; the one thing to watch is a parent with `overflow: hidden` right round it, which would cut off a hop.
## Behaviour
- **Pointer play.** With `interactive` on (the default), the head and eyes follow a nearby pointer, and a click makes it hop with a full spin and a happy face.
- **Small sizes.** For avatars in a list, `antenna={false}` drops the antenna's stem and its light, keeping the knob on top, so the head itself fills more of the box (the square, circle and hexagon grow; the wide rectangle is already as big as its width allows).
- **Reduced motion.** With `prefers-reduced-motion: reduce`, or `paused`, the still pose of the state is drawn in