pipkins

There's one for everyone.

Any name, email or id gets a small animal of its own. The same name always gets the same one, and nothing is stored.

Get started
pipkin("theo")  
SVG for this pipkin≈2 KB
Dependencies0
Species, earless blob included6
Time to draw one, on this device<1 ms

Get yours in one line.

No dependencies and about 8.9 KB gzipped. Each pipkin is an SVG string, so it works in React, Vue, Svelte or a plain template.

Install
$ i pipkins
Use it
Avatar.jsx
import { pipkin } from "pipkins";

export function Avatar({ id }) {
  const svg = pipkin(id, { size: 32 });
  return <span dangerouslySetInnerHTML={{ __html: svg }} />;
}

No bundler? Import it from a CDN: https://cdn.jsdelivr.net/npm/pipkins@0/dist/pipkins.min.js

Made for crowded places.

Comments, chats, cursors, leaderboards. Hundreds can share one page, because a pipkin has no ids, defs or filters to collide.

# design-crew 4 members
  1. zoe10:02

    Pushed the new onboarding flow. Can someone check the empty states?

  2. priya10:04

    On it. The member list still reads well at 24 px.

  3. noah10:05

    Where do we store everyone's avatar?

  4. ava10:05

    We don't. Same name, same pipkin, every time.

Stick them anywhere.

Comments, cursors and team badges, plus the tricks: breed two, fuse a team, change the mood.

Fuse a team into a badge

fuse(["zoe", "priya", "noah", "ava"])
juno

Love the new empty state.

kofi

Can we keep the bunny?

Comments and cursors

pipkin(user.id)

Breed any two

Eight moods

A small API, no surprises.

Everything returns a string or a plain object. Bad values throw a TypeError that names the accepted ones.

Functions

FunctionReturnsNotes
pipkin(seed, options?)SVG stringOne pipkin. A seed is any name, id or email, a lineage, or a genome.
fuse(seeds, options?)SVG stringOne pipkin for up to 9 members. Order and duplicates are ignored.
breed(a, b, { child? })genomeOrder-free. child picks a sibling (0, 1, 2…).
pipkinUri, fuseUridata URIThe same, ready for src attributes.
describe(seed)stringAlt text, such as "pink bunny with dot eyes".
genome(seed)genome{ id, gen, genes, from, parents }. from says which parent each trait came from.
share(trait, value)numberHow common a trait value is: share("species", "fox") is 0.16.

Options

OptionDefaultNotes
sizenoneSets width and height. Leave it out to size with CSS.
backgroundfalse"circle", "squircle" or "square", in a pale tint of the pipkin's colour.
mood"neutral"happy, sleepy, grumpy, worried, excited, determined, smug.
animatefalsetrue, or "hover" to play only while hovered. Load pipkins/motion.css once.
embedMotionfalsePuts the motion CSS inside the SVG, so it animates on its own, even as an <img>.
titlenoneAccessible name. Without it the SVG is aria-hidden.

Guarantees

  • Deterministic. The same input gives the same SVG, byte for byte. 41 pinned renders are checked on every test run.
  • Normalised names. Case, spacing and Unicode form don't change the pipkin, so "Theo " is "theo".
  • Stable traits. Each trait is hashed on its own key, so a new trait never moves the old ones. Changing how pipkins look is a major version.
  • Legible. Eyes clear 6.8:1 contrast against every body colour, and pipkins are checked down to 16 px.
  • Safe to repeat. No ids, <defs>, gradients or filters, so hundreds of pipkins can share a page.
  • Private. Nothing is stored or sent anywhere. Every pipkin on this page was drawn in your browser.