Skip to content

Manual Usage

@avatar-generator/core gives you one function, createAvatar(style, options), which returns an SVG string. No framework, no DOM, no build step required.

Basic usage

import { createAvatar } from "@avatar-generator/core";
import { initials } from "@avatar-generator/style-initials";
const avatar = createAvatar(initials, {
seed: "Hugo GB",
size: 64,
});
// The raw SVG markup
console.log(avatar.svg);
// …or a data URI for an <img>
const img = document.createElement("img");
img.src = avatar.toDataUri();
document.body.appendChild(img);

The package is plain JavaScript with type declarations alongside it, so the same code works unchanged in a .js file — drop the type imports and nothing else changes.

avatar.svg is a complete <svg> element as a string. Inline it when you control the surrounding markup — it is smaller than a data URI and styleable with CSS. Use toDataUri() when you need something that fits in an src attribute.

Using different styles

A style is just an object you pass as the first argument, so switching styles means switching imports.

import { createAvatar } from "@avatar-generator/core";
import { initials } from "@avatar-generator/style-initials";
import { geometric } from "@avatar-generator/style-geometric";
import { pixels } from "@avatar-generator/style-pixels";
import { rings } from "@avatar-generator/style-rings";
import { faces } from "@avatar-generator/style-faces";
import { illustrated } from "@avatar-generator/style-illustrated";
import { anime } from "@avatar-generator/style-anime";
import { abstract } from "@avatar-generator/style-abstract";
import { emoji } from "@avatar-generator/style-emoji";
import { animals } from "@avatar-generator/style-animals";
import { gradient } from "@avatar-generator/style-gradient";
// One seed, eleven different deterministic results
const seed = "user-123";
const all = [initials, geometric, pixels, rings, faces, illustrated, anime, abstract, emoji, animals, gradient].map(
(style) => createAvatar(style, { seed }),
);

Shared options

Every style accepts these, whatever it draws:

import { createAvatar } from "@avatar-generator/core";
import { geometric } from "@avatar-generator/style-geometric";
const avatar = createAvatar(geometric, {
seed: "unique-id", // required — drives every choice
size: 128, // pixels (default: 64)
square: true, // square instead of circle (default: false)
transparent: false, // transparent background (default: false)
colors: ["#FF6B6B", "#4ECDC4", "#45B7D1"], // palette to pick from
border: { width: 2, color: "#333" }, // optional border
rotate: 45, // degrees (default: 0)
flip: false, // horizontal flip (default: false)
scale: 0.9, // scale factor (default: 1)
});

colors is a palette, not a single background: the style picks from it using the seed, so two users with the same palette still get different colors.

Style-specific options

Each style also owns its own option type, exported from its own package:

import { faces, type FacesOptions } from "@avatar-generator/style-faces";

Anything you leave unset is chosen deterministically from the seed. Setting a value pins it for every seed — useful for a themed set, but it removes that dimension of variety.

Initials

import { initials } from "@avatar-generator/style-initials";
createAvatar(initials, {
seed: "john.doe@example.com",
name: "Hugo GB", // name to take initials from (default: the seed)
fontFamily: "Arial", // default: "sans-serif"
fontWeight: 700, // default: 600
textColor: "#ffffff", // default: "#fff"
});

Splitting seed from name is the point of this style: seed on the stable user ID so the color never changes, and display whatever name you currently have.

Geometric

import { geometric } from "@avatar-generator/style-geometric";
createAvatar(geometric, {
seed: "unique-id",
gridSize: 5, // default: 5; odd values stay symmetrical
padding: 1, // cells of padding around the pattern (default: 1)
foregroundColor: "#2C3E50", // default: picked from the palette
});

Pixels

import { pixels } from "@avatar-generator/style-pixels";
createAvatar(pixels, {
seed: "unique-id",
pixelSize: 8, // grid resolution (default: 8)
skinTones: ["#FFDBB4"], // default: the SKIN_TONES palette
accessories: true, // allow glasses (default: true, 15% chance)
featureColor: "#2C1810", // eyes and mouth
});

Rings

import { rings } from "@avatar-generator/style-rings";
createAvatar(rings, {
seed: "unique-id",
ringCount: 5, // default: 4
ringGap: 3, // default: 2
segmented: true, // allow pie-slice rings (default: true)
dashed: true, // allow dashed rings (default: true)
centerStyle: "diamond", // "solid" | "dot" | "ring" | "diamond" | "none"
});

Faces

import { faces } from "@avatar-generator/style-faces";
createAvatar(faces, {
seed: "unique-id",
skinTones: ["#FFDBB4"], // default: the SKIN_TONES palette
featureColor: "#2C1810", // eyes, mouth, eyebrows
eyebrows: true, // default: true (50% chance)
ears: true, // default: true (40% chance)
nose: true, // default: true (30% chance)
hairStyle: "side-swept", // "none" | "flat-top" | "cap" | "side-swept" | "spiky" | "round-top" | "mohawk" | "beanie"
eyeStyle: "round", // "dots" | "rectangles" | "lines" | "round"
mouthStyle: "rect-smile", // "line" | "rect-smile" | "open-rect" | "zigzag" | "dot"
});

Illustrated

import { illustrated } from "@avatar-generator/style-illustrated";
createAvatar(illustrated, {
seed: "unique-id",
hairStyle: "afro", // 12 styles
eyeStyle: "round", // 8 styles
eyebrowStyle: "natural", // 6 styles
noseStyle: "button", // 5 styles
mouthStyle: "bigSmile", // 8 styles
glasses: true, // default: true (20% chance)
hat: true, // default: true (10% chance)
earrings: true, // default: true (8% chance)
facialHair: true, // default: true (15% chance)
});

Anime

import { anime } from "@avatar-generator/style-anime";
createAvatar(anime, {
seed: "unique-id",
hairStyle: "twin-tails", // 10 styles
eyeStyle: "sparkly", // 8 styles
mouthStyle: "cat-mouth", // 6 styles
noseStyle: "dot", // "dot" | "line" | "shadow"
bangs: true, // default: random (60% chance)
ahoge: true, // the stray hair strand (default: random, 40%)
blush: true, // default: random (35% chance)
accessories: true, // bandaid, headband (default: true)
});

Abstract

import { abstract } from "@avatar-generator/style-abstract";
createAvatar(abstract, {
seed: "unique-id",
composition: "bauhaus", // "mondrian" | "kandinsky" | "bauhaus"
shapeCount: 3, // accent shapes in the Kandinsky composition (default: 3)
});

Emoji

import { emoji } from "@avatar-generator/style-emoji";
createAvatar(emoji, {
seed: "unique-id",
expression: "laughing", // "happy" | "laughing" | "cool" | "wink" | "love"
// | "sad" | "angry" | "surprised" | "sleepy" | "neutral"
faceColor: "#FFD93D", // default: the yellow emoji palette
});

Animals

import { animals } from "@avatar-generator/style-animals";
createAvatar(animals, {
seed: "unique-id",
animal: "fox", // "cat" | "dog" | "bear" | "fox" | "panda" | "bunny" | "frog" | "monkey"
furTones: ["#C68B59"], // default: earth tones
});

Gradient

import { gradient } from "@avatar-generator/style-gradient";
createAvatar(gradient, {
seed: "unique-id",
direction: "radial", // "linear" | "radial" | "diagonal"
pattern: "waves", // "none" | "dots" | "stripes" | "waves" | "grid"
colorStops: 3, // 2 or 3 (default: 2)
});

Building option pickers

Each style exports the arrays behind its literal unions, so a settings UI can be generated rather than hand-maintained:

import { faces, HAIR_STYLES, EYE_STYLES, MOUTH_STYLES } from "@avatar-generator/style-faces";
for (const hairStyle of HAIR_STYLES) {
renderOption(hairStyle, createAvatar(faces, { seed: "preview", hairStyle }));
}

Determinism

The same seed and options always produce the same result:

const a = createAvatar(initials, { seed: "user-123" });
const b = createAvatar(initials, { seed: "user-123" });
a.svg === b.svg; // always true

That holds across processes and platforms, not just within one page — a Node server render and a browser render of the same seed produce identical bytes. So you never need to store a generated avatar: the seed is the storage.

Seed on something stable, like a user ID. Seeding on an email or display name means the avatar changes when the user does.

Next