Avatar Generator

Creates and edits avatars.

@paneui/theme@paneui/avatar@paneui/button@paneui/input@paneui/select@paneui/tabs@paneui/icons@base-ui/react@dicebear/core@^9.4.3@dicebear/notionists@^9.4.3
Avatar for hana

The same seed always draws the same avatar.

Gender
Hair
Eyes
Brows
Mouth
Glasses
Beard
Top
Gesture

Installation

pnpm dlx shadcn@latest add @paneui/avatar-generator

Usage

Composition

Examples

From a Seed

Use a stable seed, like a user id, so a person gets the same avatar everywhere.

Male and Female

Options

Generator

Artwork and licence

The illustrations and the renderer install with the component as two packages; nothing is fetched at runtime. The licence metadata block is stripped from the SVG output; credits for the art and the renderer are in THIRD_PARTY_NOTICES.md.

Parts

Part names follow the drawing set, with hair variant01…variant63 plus hat, eyes variant01…05, brows 01…13, lips 01…30, nose 01…20, glasses 01…11, beard 01…12, body (the top) 01…25, and gesture waveLongArms, waveLongArm, wavePointLongArms, waveOkLongArms, pointLongArm, okLongArm, handPhone. Use getAvatarParts(slot, gender) for the list with labels. Gestures are off unless picked; the set's point, ok and hand are left out because the closer crop hides the hand.

Small sizes and ids

The drawings are busts; the avatar is zoomed in (scale 135, translateY 8) so the face still reads at xs/sm (20–24px). Every id inside the SVG (the clip mask, some tops) is prefixed. GeneratedAvatar and GeneratedAvatarImage use React's useId, createGeneratedAvatar a hash of the options (or your idPrefix), so any number of avatars, identical ones included, can share a page without one borrowing another's mask, and the markup is the same on the server and the client.

Storing an avatar

Store the seed when the avatar can be regenerated from the user. When the user edits it, store { seed, gender, selections, accessories } from onValueChange. A future release of the drawing set that adds parts can change seed-only picks, so pin explicit selections for avatars that must never change.

Generator width

AvatarGenerator lays out by its own width, not the screen's: stacked below 36rem, preview beside the controls from there. Size it with className (it fills its parent up to max-w-2xl).

Dark mode

The line art is black on white faces, so the default tint background stays light in both themes. Use background="none" only on light surfaces.

API Reference

GeneratedAvatar

A seeded illustrated avatar inside the library's Avatar frame. Children (e.g. AvatarStatus) render on top. Also accepts every prop of Avatar.

seed*
string
Any stable string.
gender= "any"
"male" | "female" | "any"
Which hairstyles the seed picks from. female has 22 (long hair, bobs, buns, ponytails, headscarves) and never a beard; male has 35 short cuts and allows a beard; any uses all 64.
size= "md"
"xs" | "sm" | "md" | "lg" | "xl" | number
An Avatar size or a pixel size. Inside an AvatarGroup it follows the group.
shape= "circle"
"circle" | "rounded"
Passed to Avatar.
accessories= false
boolean
Let the seed add glasses (about one in three).
background= "tint"
"tint" | "circle" | "none" | string
tint is a light grey square, circle the same tint as a disc, none transparent, or pass a hex colour.
selections
{ hair?, eyes?, brows?, lips?, nose?, glasses?, beard?, body?, gesture?: string }
Explicit part per slot by name ({ hair: "variant46", glasses: "none" }). Overrides the seed; the Parts note lists the names.
colors
{ background?: string }
Hex colour for the background tint.
idPrefix
string
Prefix for ids inside the SVG. Defaults to one from useId (a hash of the options in createGeneratedAvatar).
title
string
Accessible name. Without it the avatar is decorative.
PropTypeDefaultDescription
seed*string—Any stable string.
gender"male" | "female" | "any""any"Which hairstyles the seed picks from. female has 22 (long hair, bobs, buns, ponytails, headscarves) and never a beard; male has 35 short cuts and allows a beard; any uses all 64.
size"xs" | "sm" | "md" | "lg" | "xl" | number"md"An Avatar size or a pixel size. Inside an AvatarGroup it follows the group.
shape"circle" | "rounded""circle"Passed to Avatar.
accessoriesbooleanfalseLet the seed add glasses (about one in three).
background"tint" | "circle" | "none" | string"tint"tint is a light grey square, circle the same tint as a disc, none transparent, or pass a hex colour.
selections{ hair?, eyes?, brows?, lips?, nose?, glasses?, beard?, body?, gesture?: string }—Explicit part per slot by name ({ hair: "variant46", glasses: "none" }). Overrides the seed; the Parts note lists the names.
colors{ background?: string }—Hex colour for the background tint.
idPrefixstring—Prefix for ids inside the SVG. Defaults to one from useId (a hash of the options in createGeneratedAvatar).
titlestring—Accessible name. Without it the avatar is decorative.

GeneratedAvatarImage

The drawing alone as an <svg> that fills its box. Same options as GeneratedAvatar minus size and shape. Also accepts every prop of svg.

createGeneratedAvatar

Framework-free builder. Returns { selections, viewBox, content, toString(size?), toDataUri(size?) }; selections is the part each slot ended up with ("none" for an empty optional slot).

options*
GeneratedAvatarOptions
Same options as GeneratedAvatar (seed, gender, accessories, background, selections, colors).
PropTypeDefaultDescription
options*GeneratedAvatarOptions—Same options as GeneratedAvatar (seed, gender, accessories, background, selections, colors).

getAvatarParts

The parts a slot offers for a gender, for building your own pickers. Only hair differs by gender (and beard is empty for female); glasses, beard and gesture start with none.

slot*
"hair" | "eyes" | "brows" | "lips" | "nose" | "glasses" | "beard" | "body" | "gesture"
Returns { name, label, gender? }[].
gender= "any"
"male" | "female" | "any"
PropTypeDefaultDescription
slot*"hair" | "eyes" | "brows" | "lips" | "nose" | "glasses" | "beard" | "body" | "gesture"—Returns { name, label, gender? }[].
gender"male" | "female" | "any""any"

AvatarGenerator

The editor UI. Also accepts every prop of div.

defaultSeed= "paneui"
string
Initial seed.
defaultGender= "any"
"male" | "female" | "any"
Initial gender.
onValueChange
(state: { seed, gender, selections, accessories }) => void
Called on every change; store it to redraw the same avatar with GeneratedAvatar.
PropTypeDefaultDescription
defaultSeedstring"paneui"Initial seed.
defaultGender"male" | "female" | "any""any"Initial gender.
onValueChange(state: { seed, gender, selections, accessories }) => void—Called on every change; store it to redraw the same avatar with GeneratedAvatar.