Documentation
Avatarsverse is a free, open-source library of avatar images served over a global CDN.
Overview
Every avatar is available directly from jsDelivr. The @main URL tracks the latest repository state. For stable production URLs, replace it with an existing Git release tag. You can drop the URL into an <img> tag without running an image backend.
The NPM package adds a deterministic mapping from any string to an avatar URL. Pass the same seed (email, username, user ID) and you will always get the same avatar back, across devices and deployments.
Currently one style is available: voxel. More styles are in the works — follow the GitHub repo to get notified.
Installation
To use avatar URLs directly, there is nothing to install. Copy a URL from the homepage and use it as-is. For the deterministic helper in a JS/TS project, install the package with your preferred package manager: npm install avatarsverse.
<img
src="https://cdn.jsdelivr.net/gh/coppermare/avatarsverse@main/avatars/voxel/1.jpeg"
alt="Avatar"
width="64"
height="64"
/>Usage
Import avatarUrl and pass any string as the seed. The function hashes the seed and returns a CDN URL. A common pattern is to fall back to a deterministic avatar when a user hasn't uploaded a photo yet — use user.avatarUrl ?? avatarUrl(user.id).
import { avatarUrl } from "avatarsverse";
const url = avatarUrl("alice@example.com");
// → always the same avatar for this seed
<img src={url} alt="Alice" width={64} height={64} />Next.js
When using the optimized Next.js Image component, allow the jsDelivr hostname in your image configuration:
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{ protocol: "https", hostname: "cdn.jsdelivr.net" },
],
},
};
export default nextConfig;import Image from "next/image";
import { avatarUrl } from "avatarsverse";
<Image
src={avatarUrl(user.id)}
alt={`Avatar for ${user.name}`}
width={64}
height={64}
/>Package API
avatarUrl(seed, category?, total?, tag?)
Returns a jsDelivr CDN URL for the avatar deterministically selected by the given seed.
| Parameter | Type | Default | Description |
|---|---|---|---|
| seed | string | required | Any string used to deterministically pick an avatar |
| category | string | "voxel" | Avatar style to draw from |
| total | number | undefined | Limits selection to the first N files in the category manifest |
| tag | string | "main" | jsDelivr release tag — pin to a version to freeze avatar assignments |
Returns string — a fully-qualified CDN URL.
The function throws when the seed is empty, the category does not exist, or the pool limit is outside the available range.
cyrb53(value, seed?)
Returns a deterministic numeric hash. The optional numeric seed defaults to zero. This low-level export powers avatar selection; most applications should use avatarUrl instead.
HTTP API
The Next.js app exposes read-only endpoints for self-hosted deployments. All routes accept GET and OPTIONS and return permissive CORS headers.
GET /api/avatars
Lists every category and its filenames.
{
"categories": {
"voxel": ["1.jpeg", "2.png"]
}
}GET /api/avatars/:category
Lists filenames for one category.
{ "files": ["1.jpeg", "2.png"] }GET /api/avatars/:category/:id
Returns the image bytes with the detected PNG or JPEG content type. The ID may include its extension, such as /api/avatars/voxel/1.jpeg, or omit it, such as /api/avatars/voxel/1. Add ?download=1 to receive it as a file attachment.
const response = await fetch("/api/avatars/voxel/1");
const image = await response.blob();
// Direct file download
const downloadUrl = "/api/avatars/voxel/1?download=1";Manifest responses are cached for five minutes with stale revalidation. Image responses are cached immutably for one year. Missing categories and images return HTTP 404 with { "error": { "code": "not_found", "message": "..." } }.
FAQ
Why am I getting a different avatar on another device?
The seed must be exactly the same. Pick one stable identifier per user (e.g. a user ID) and use it consistently.
Will avatars change if I update the package?
They can. The avatar selected for a seed is determined by the manifest bundled inside the package. If a new version adds avatars to the pack, the mapping shifts. To freeze assignments, pin both your package version in package.json and pass the matching release tag as the fourth argument so the CDN URL stays consistent too:
avatarUrl(
"alice@example.com",
"voxel",
undefined,
"<existing-release-tag>"
)Is there a rate limit or cost?
Avatarsverse has no account requirement or usage fee and is released under the MIT license — free for personal and commercial use. Image delivery is provided by jsDelivr and remains subject to its service and fair-use policies.
Can I self-host?
Yes. Clone the GitHub repo and serve the avatars/ folder from your own CDN. Update the CDN_BASE constant in index.ts to point to your URL.
Will more avatar styles be added?
Yes, more packs are planned. Watch the GitHub repo for releases.