Avatars from
a string.

seedicon turns any string into a deterministic SVG avatar. Same seed in, same avatar out, forever. Nothing is uploaded, stored, resized or moderated: the only thing you keep is the ID you already had.

Try itSource
Zero dependencies, zero stored images.Read the docs
0
Downloads / week
2
GitHub stars
v0.3.1
Latest version
0
Dependencies

Preview

One wallet address, two styles: a drawn character and a walk across a board. Both are rendered on the server, so everything below is markup rather than a canvas. To change the seed, style, size or corner radius and watch it redraw, use the playground.

pixelartA pixel-art character with hair, eyes and a top.
96px
56px
40px
24px
16px
import { Avatar } from "seedicon/react";

<Avatar
  seed="0xba32a6076cd558947b3da6148fc4994b421eed56"
  style="pixelart"
  size={96}
  shape="rounded"
/>
randomartThe drunken bishop from ssh-keygen, drawn in color.
96px
56px
40px
24px
16px
import { Avatar } from "seedicon/react";

<Avatar
  seed="0xba32a6076cd558947b3da6148fc4994b421eed56"
  style="randomart"
  size={96}
  shape="rounded"
/>

Styles

18 styles, all rendered on the server here — seedicon has no canvas and no window access, so it works during SSR in Next.js, Remix or anything else. Three of them are output-compatible with an existing library, so you can swap it out without changing anyone's avatar. Each one is described in full, with the shape and radius options, on the docs page.

pixels

Mirrored pixel grid. Output-compatible with blockies.

identicon

Five symmetric rows. The classic dev-tool identicon.

jdenticon

Geometric shapes, four-fold symmetry. Compatible with Jdenticon.

stellar

7x7 mirrored bit grid. Reads real Stellar keys.

randomart

The drunken bishop from ssh-keygen, drawn in color.

lifehash

A pattern grown with a Game of Life automaton.

dither

A two-tone gradient through a Bayer threshold matrix.

pixelart

A pixel-art character with hair, eyes and a top.

truchet

Quarter-circle tiles that always join into loops.

heraldry

A division of the field with a charge over it.

kaleidoscope

Shapes folded around a center with N-fold symmetry.

streamlines

Particles combed through a seeded vector field.

moire

Line gratings at close angles, beating against each other.

terrain

Five landscape ridges stacked over a flat sky.

marble

Two blurred organic blobs over a flat color.

waves

Layered wave bands in shades of a single hue.

gradient

A soft two or three stop diagonal gradient.

glass

Two blurred white glows over a saturated color.

Usage

Two functions and one optional React component. That is the whole API — pick the one that matches where you render. The docs cover every option, including the square, rounded and circle shapes.

Anywhere · returns string — raw <svg> markup

import { generateAvatar } from "seedicon";

const svg = generateAvatar({
  seed: user.id,
  style: "truchet",
});
runs during SSR: no canvas, no window

The same wallet address where people actually meet an avatar: a profile card, a chat, notifications, a comment thread, a stack of assignees. Everyone else in the panel is seeded from the kind of id real apps pass in (an email, a username, a UUID), so you can judge whether a style tells people apart, not only whether one avatar looks good. Switch the style from the bar at the top of the panel.

Edit profile
You
0xba32a6076cd558947b3da6148fc4994b421eed56
12 projects5 teammates
Messages#onboarding

Is the new avatar picker live yet?

Yes. Every account already has one, generated from the user id.

Same picture on my phone and on my laptop. Nothing to upload?

Nothing stored anywhere. Same seed, same avatar.

Mine came out great. Shipping it.

Notifications3

Maria Souza mentioned you in Onboarding v2

2 min

user_8812 approved your pull request

1 h

0x5aAe…BeAed joined the workspace

1 d
Comments2
you · 2 min ago

Shipped the new onboarding flow. Avatars come straight from the user id.

user_8812 · just now

Looks great at small sizes too.

AssigneesOnboarding v2
+8

You and 13 others are working on this.

FAQ

Everything you need to
know about seedicon

Not here? The docs go through every option, and anything still missing is worth an issue on GitHub.

Why not just let people upload a photo?

Because an upload is never only an upload: you store the file, resize it, moderate it, serve it, and you still need something to show for every account that never uploaded anything. Most products want that last part and nothing else — a slot that looks intentional and stays the same on every screen. seedicon fills it from an id you already have, so there is no file, no bucket and no CDN in the picture.

How does it actually work?

The seed is run through a fast 32-bit hash, and the style reads numbers off that hash to decide cell colours, angles, offsets and how many shapes to draw. The result is written out as an <svg> string.

There is no randomness and no I/O anywhere in that path, so the same { seed, style, size, shape, radius } gives byte-for-byte identical markup — on your laptop, on the server, in a Deno worker, next year.

Can I ship a single style instead of all of them?

Yes, and it is the recommended thing to do if you picked one and stuck with it. Every style has its own entry point: import { pixels } from "seedicon/pixels" pulls in that one renderer plus the shared core, and nothing else: 1.3 kB minified and gzipped against 14.3 kB for the root entry. The One style only section above has the figure for every style.

The root entry resolves styles by name, so it has to reference all 18 of them and no bundler can drop the ones you never call. The <Avatar> component takes a style name too, which means it pulls in the whole registry — if bundle size matters more than the convenience, call the single-style function and render the markup yourself.

Does it render on the server?

Yes. String in, string out — no canvas, no window, no useEffect, no ref to attach anything to. It runs during SSR in Next.js or Remix, and equally well in a Node script, an email template or anything else that emits HTML. Every avatar in the gallery above was rendered on the server.

Can I control the shape and size?

shape is one of square, rounded or circle, and radius overrides it when none of the three is the corner you want. The presets are a fraction of size rather than a fixed pixel count, so the same shape holds at 16px and at 256px.

The corner is a clip applied over the finished artwork, so it behaves identically for every style.

What do I have to store in the database?

Nothing, in the common case: call generateAvatar at render time with the user id or wallet address you already have. If you want people to be able to change their style, store the style name in a plain string column and pass it through — that is one short string per user, not an image.