3D Avatar Engine Development for React by Peeyush Singh3D Avatar Engine Development for React by Peeyush Singh

3D Avatar Engine Development for React

Peeyush Singh

Peeyush Singh

claykit: 3D clay avatars for React, built from real geometry

claykit is an open-source avatar engine. You give it a small JSON file that describes a creature (a head, ears, eyes, and the expressions it can make), and it draws an animated clay character that turns, blinks and changes mood on cue.
The demo character is Freddy. He has 28 expressions and 6 animations, and comes in two finishes: clay, with a gradient, bevel, grain and soft contact shadow, and plastic, a flat two-tone look. In the demo, pick a finish, an animation or a pose, and Freddy moves to it smoothly.
It ships as two MIT-licensed packages on npm:
<AvatarCanvas definition={freddy} finish="clay" animation="idle" size={240} />

The problem

My first version drew the avatar as a flat outline: 64 numbers, one per angle around the shape. It was only 4KB and looked convincing face-on.
Turn it more than about twenty degrees and it fell apart. Nothing behind the outline had a position in space, so there was nothing real to rotate. I wanted a head that turns because it's actually there.
The clay finish in an upward-side-glance. The head really turns in 3D, so the ears stay separate and the eyes foreshorten with the face.
The clay finish in an upward-side-glance. The head really turns in 3D, so the ears stay separate and the eyes foreshorten with the face.

What didn't work

The obvious next step was to blend 3D shapes into one smooth surface. I built that first, and it was worse. The ears melted into the head instead of reading as ears, and the whole shape warped as it turned.
The same version had two more bugs that looked fine at a glance but failed on a screenshot. Eye angles were read as radians when they had been written in degrees, so every tilted eye was off by about 57×. And the eyes were flat ellipses slid around the face, so they looked like stickers.
Blending was the wrong tool. A head with ears is several separate shapes that happen to touch, and blending erases the seam that keeps them apart.

What I built instead

Every shape is drawn on its own. The head and each ear are sampled as 3D points, posed, rotated with the head, put into perspective and wrapped in an outline. Every shape claykit supports is convex, so that outline is the exact silhouette, not an approximation. An ear stays an ear.
Layering is decided once. Each part is marked as behind or in front of the head when the avatar is written. Nothing is re-sorted every frame, so parts can't flicker through the head mid-turn.
Eyes sit on the face in 3D. They're placed on the head's real front surface and turn with it, so they foreshorten and roll like part of the face instead of floating on top.
Two numbers, measured instead of guessed. Perspective strength was fitted by rendering a turn and measuring how much the far side should compress. A shape setting that controlled both corner rounding and turning width had to be split in two: shared, it looked right at rest but cut the head's movement to about 60% of what it should be. Measuring the outline's width across a turn caught it, where looking at a still frame never would.
Colour changes blend smoothly. An expression can tint the body, the eyes or both, and the colour blends over the transition instead of snapping. angry-brows flushes Freddy red.
Freddy in the plastic finish: flat and two-tone, no bevel or grain. Same avatar file, one prop changed.
Freddy in the plastic finish: flat and two-tone, no bevel or grain. Same avatar file, one prop changed.

Why it matters for client work

- Real structure over tricks. When something has to move convincingly, I build what's actually there instead of faking the appearance of it.
- I measure, not just eyeball. The bugs that matter most often look fine in a still frame. I test motion in motion.
- Small, clean APIs. One component, one JSON file, two finishes. The engine has no React dependency, so it can work in other frameworks.
- Shipped, not just prototyped. Published on npm with a full spec, so anyone can design their own creature.

Credits

Freddy's poses and animation set take direct inspiration from avatars.bible-strong.app, which I used as a reference for the range of expressions before writing my own. The engine, geometry, rendering and React binding are my own work.

Like this project

Posted Oct 14, 2026

A clay avatar that turns, blinks and emotes because it's built in real 3D, not faked in 2D. 28 expressions, 6 animations, two finishes.