All projects

Work · 2026

avatarGenerator

Turns a name into the same avatar every time, entirely offline and with no dependencies.

LiveSource

At a glance

  • Runs without an npm package, a CDN or a network request
  • Deterministic through NFC normalisation, an FNV-1a hash and a Mulberry32 PRNG
  • Available as a character, an abstract pattern or initials
  • Billions of possible combinations in the character style

The problem

Placeholder avatars for users without a picture of their own usually come from Gravatar or DiceBear. That means one external request per avatar, the visitor’s IP address handed to another service, and a dependency you have no say over. For a 128×128 image, that is quite a lot.

How it works

The generator works the image out for itself, from the name alone.

The name is first normalised to NFC, so that “José” produces the same value whether it arrived NFC- or NFD-encoded. An FNV-1a hash turns that into a 32-bit seed, which initialises a Mulberry32 PRNG. That PRNG then draws every visible trait in a fixed order: skin tone, hairstyle, hair colour, eyes, brows, nose, mouth, beard, clothing, glasses, headwear, earring, freckles and the background gradient.

Same name, same seed, same image. On any device and in any session, without storing anything anywhere.

import { generateAvatar } from './avatarGenerator.js';

const svg = generateAvatar('John Doe', { size: 128 });
document.getElementById('avatar').innerHTML = svg;

The face

The face took more work than the randomness. A circle with two dots reads as a placeholder, so the head is built from Bézier curves, with consistent outlines, soft shading and a subtle sticker shadow. That way ten avatars side by side look like a set rather than ten unrelated results.

There is one constraint when extending it: the order of the PRNG calls is part of the library’s public behaviour. Inserting a new trait in the middle of the chain shifts every subsequent draw and changes every avatar that already exists. New traits therefore go at the end.

Integration

generateAvatar() returns a complete SVG string including xmlns, ready to drop into innerHTML or a template. For projects that use dependency injection there is also a thin AvatarGenerator class, which holds default options in its constructor and otherwise just passes things along.

The live demo below uses exactly that file.

Live demo

The generator runs directly in your browser, with no server and no network request. The same name always gives the same avatar.

The live demo needs JavaScript. The source code is linked either way.