A different seed, a different possibility. Use title or an accessible label for meaningful avatars; otherwise the component is decorative.
Using Next.js or server rendering?
The package’s React entry point declares 'use client' and uses React’s useId for safe SVG IDs. You can import it in a Next.js page. Put interactive controls in a Client Component. If your application has multiple React roots, give each root its own matching server/client identifierPrefix.
Use the core renderer for HTML, server-side generation, or another framework. The core and collection imports don’t load React or fetch artwork.
avatar.ts
import { createAvatar } from'@illlustrations/avatars';
import { croods } from'@illlustrations/avatars/croods';
const avatar = createAvatar(croods, {
seed: 'alex',
size: 64,
shape: 'circle',
background: '#EDEDFF',
});
// Use an image in your page. No React required.const image = document.createElement('img');
image.src = avatar.toDataUri();
image.alt = "Alex's avatar";
document.body.append(image);
For server-side output, use avatar.toString(). When inserting multiple inline SVG strings into one page, pass a unique idPrefix to each toString() call.
A seed picks one combination from a frozen, versioned pool. The same seed and style version give the same avatar on the server, the client and every device, so you don’t need to store anything for generated profiles.
TSX · seeds
// Same seed, same avatar: on the server, the client and every device.
<Avatar assets={croods} seed={user.id} />
// Seeds pick head, face, outfit and glasses. Facial hair is opt-in.
<Avatar assets={croods} seed={user.id} selections={{ facialHair: 'beard' }} />
// Explicit selections always win over the seed.
<Avatar assets={croods} seed={user.id} selections={{ head: 'bun', face: 'happy' }} />
seed="maya"
seed="maya" again
+ facialHair: 'beard'
+ head: 'bun'
Use a stable ID
Seed with a user ID, not a display name or Math.random(). Names change; random seeds change on every render and cause hydration mismatches.
Facial hair is opt-in
Seeds pick hair, face, outfit and glasses, but never facial hair. Add it with selections when someone chooses it.
Resolution order: style defaults → seeded combination → explicit selections. Different seeds can land on the same avatar.
Three layers, applied in order: a theme recolors everything, a palette swaps any artwork color, and the four colors roles always win.
Roles
hair, skin, clothing and stroke take one color, or a list the seed picks from.
Palette
Swap any color in the artwork by its hex, like the builder: the bag, mouth, drool and other accents.
Your brand colors, one per person
Pass a list and the seed picks one entry. Each person keeps their color everywhere, and a team gets your whole palette.
TSX · color lists
// One color, or a list: the seed picks one entry per person, every time.
<Avatar
assets={croods}
seed={user.id}
colors={{ clothing: ['#254CE9', '#F76549', '#77E87B'], hair: ['original', '#272727'] }}
background={['#DDE5FF', '#FFE6D2', '#D4EDE2']}
/>
maya
leo
priya
sam
noor
theo
jules
alex
Any artwork color
TypeScript · palette
import { createAvatar } from'@illlustrations/avatars';
import { croods } from'@illlustrations/avatars/croods';
croods.palette; // every artwork color: ['#000000', '#FF0000', '#FFFFFF', …]const avatar = createAvatar(croods, {
selections: { upperBody: 't-shirt-bag' },
colors: { hair: '#254CE9' }, // roles first
palette: { '#FF4B33': '#254CE9' }, // then any artwork color: here, the bag
});
avatar.sourceColors(); // artwork colors in this avatar's parts
#000000Outlines (stroke role)
#FF0000Hair and beard (hair role)
#FFFFFFSkin (skin role), eye whites and teeth
#313130Dark garments (clothing role)
#FF4B33Bag on t-shirt-bag
#FFE900Yellow garments (clothing role), shirt under the blazer
#FF3F3FMouth and tongue
#424242Mouth shadow
#5DECFFDrool
#F4F1EBDetail on shirt-1
A palette entry changes every use of that color. #FFFFFF is both skin and eye whites, so change skin with colors.skin. Unknown colors throw.
Chats, comments, leaderboards, onboarding and all the little places people show up. Every face below is the same <Avatar> component, with the props under each widget.
Maya Chen Online
New onboarding is live 🚀 Everyone gets an avatar on sign-up now.
No more grey circles!
Love it. Same face on web and mobile?
Yep, seeded by user ID. Nothing to store.
Perfect 🙌
Messagessize={36} shape="circle" background
Cobaltclothing and background lists
Monotheme="neutral"
Sunsethair list and a palette swap
Brand kitssame seeds · color lists, theme, palette
Save a seed for generated profiles. When someone makes an avatar their own, save the resolved JSON so their part choices and colors come back with them.
TypeScript · save & restore
import { createAvatar, fromJSON } from'@illlustrations/avatars';
import { croods } from'@illlustrations/avatars/croods';
const avatar = createAvatar(croods, {
seed: 'alex',
selections: { head: 'straight-long', accessories: 'none' },
colors: { hair: '#254CE9' },
});
// Store the resolved parts, colors, and style version.const saved = JSON.stringify(avatar.toJSON());
// Restore later using the matching style version.const restored = fromJSON(croods, JSON.parse(saved));
const svg = restored.toString();
Saved state includes the style and schema versions. Restore with the matching style version; mismatches are rejected rather than silently changing the avatar.
Just need one SVG?
The package includes 24 ready-made portraits: croods-001.svg through croods-024.svg. Import them with your bundler, or copy them into your public assets.
Coding agents guess part IDs and import paths. Give yours the skill instead: exact imports, every valid ID, the rules and the recipes. Then just ask it to “add avatars to the member list”.
Claude.ai and Claude Desktop: download skill.md, save it as SKILL.md in a folder named illlustrations-avatars, zip the folder, and upload it under Settings → Capabilities → Skills.
Priya Nair2h
The new empty states feel so much friendlier.