MIT · zero dependencies · runs offline

Deterministic avatars from anything.

Give Avaroid a string. Get a unique avatar. Give it the same string tomorrow and get the exact same one.

npm install avaroid
avatar(seed) type to regenerate
normalized
hash
variant
bot
output
network
0 requests
Example seeds

02 — Playground

Try any seed.

Every control maps 1:1 to an option. What you see here is what avatar() returns.

seed
Seed source
design
variant
size
background
radius
format
Playground avatar preview
seed
hash
size
format
bytes

03 — Determinism

Same seed. Same avatar. Always.

run 1 · laptop · node "david@example.com" Avatar for david@example.com
run 2 · a year later · edge "david@example.com" The identical avatar, generated again
input normalized avatar vs. run 1

Strings are trimmed, lowercased and Unicode-normalized before hashing, so cosmetic differences don't fork an identity. One character of real difference does.

different seeds → different avatars

    04 — Quick start

    One function. That's the API.

    Import avatar, pass a seed, get an SVG string back. Synchronous, pure, no setup. Prefer components? Each framework gets a native one.

    index.tsimport { avatar } from 'avaroid'
    
    const svg: string = avatar('david@example.com')
    
    // options are optional
    avatar('david@example.com', {
      size: 128,
      background: 'auto',
      radius: 24,
    })
    output
    Avatar returned by the quick start example

    05 — Properties

    Small on purpose.

    Avaroid does one thing. Everything it doesn't do is a dependency, a request, or a database you don't have to think about.

    1. 01

      Deterministic

      The same seed always generates the same avatar — across machines, runtimes and releases.

      f(x) = f(x)
    2. 02

      Zero network calls

      Avatars are generated locally. No CDN, no API key, no trackers in your UI.

      offline
    3. 03

      Tiny

      No dependencies and side-effect free, so bundlers keep only what you import.

      0 deps
    4. 04

      SVG-first

      Smooth curves on a seed-derived dark field, drawn on a 64-unit canvas and rendered with geometricPrecision. One asset scales from a favicon to a profile photo.

      64-unit → ∞
    5. 05

      Framework agnostic

      Works anywhere JavaScript runs — browser, Node, Bun, Deno, workers. React, Vue, Svelte and Angular components included.

      esm · types
    6. 06

      Customizable

      Control design, variant, size, background and shape. Six options, sensible defaults, nothing else.

      6 options

    06 — Examples

    One system. Endless faces.

    Wall variant

      07 — How it works

      Input to avatar, in four steps.

      Avaroid converts your input into a stable seed and uses it to drive the avatar generator. No database or stored identity mapping required.

      1. 01 input string or image bytes
      2. 02 normalize trim · lowercase · NFC
      3. 03 hash fast, non-cryptographic
      4. 04 seeded generator PRNG picks every trait
      5. → output

      08 — API reference

      avatar()

      avatar(seed, options?) → string

      Parameters

      nametypedescription
      seed string | ArrayBuffer | Uint8Array Any identity. Strings are normalized; bytes are hashed as-is — pass await file.arrayBuffer().
      options AvatarOptions Optional. Every field has a default.

      AvatarOptions

      optiontypedefaultdescription
      design 'modern' | 'classic' 'modern' Rendering style. classic keeps the original 16-unit pixel look.
      variant 'bot' | 'grid' | 'glyph' 'bot' Generator family. Same seed, different family, different look.
      size number 64 Width and height in px. The art is drawn once on a 64-unit canvas, so every size renders smooth.
      background 'auto' | 'transparent' | string 'auto' Seed-derived color, none, or any CSS color.
      radius number 0 Corner radius in px. Use size / 2 for a circle.
      format 'svg' | 'data-url' 'svg' Raw SVG markup, or a data URL ready for img.src.

      Returns

      string — SVG markup, or a data URL when format: 'data-url'.

      Errors

      TypeError for a value of the wrong type, RangeError for an out-of-range or unknown option.

      Components

      <Avatar seed … /> from /react, /vue and /svelte, and <avaroid-avatar> from /angular take the same options plus alt, and render an <img>.