npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

quick-avatar

v0.2.4

Published

Deterministic PNG avatars for your projects. No API needed.

Downloads

225

Readme

quick-avatar

Deterministic PNG avatars for your projects. Pick a seed, get an avatar — no API, no server, no network required.

Inspired by DiceBear, but uses hand-crafted PNG illustrations instead of generated SVGs.


Installation

npm install quick-avatar

Usage

Basic (SPA / Browser)

import { createAvatar, doteye } from 'quick-avatar';

const avatar = createAvatar(doteye, { seed: '[email protected]' });

// Async: lazy-loads only the matching image chunk (~50 KB)
const src = await avatar.toDataUri();
// → "data:image/png;base64,..."

Same seed always returns the same avatar.

React

import { useEffect, useState } from 'react';
import { createAvatar, doteye } from 'quick-avatar';

function Avatar({ userId }: { userId: string }) {
  const [src, setSrc] = useState('');

  useEffect(() => {
    createAvatar(doteye, { seed: userId }).toDataUri().then(setSrc);
  }, [userId]);

  return <img src={src} width={64} height={64} alt="avatar" />;
}

CDN (zero bundle size)

Skip bundling entirely — link directly to the image file via jsDelivr:

const avatar = createAvatar(doteye, { seed: '[email protected]' });

// Default: jsDelivr pointing to the published npm package
avatar.toUrl();
// → "https://cdn.jsdelivr.net/npm/quick-avatar/dist/sets/doteye/images/39.png"

// Custom CDN or self-hosted
avatar.toUrl('https://assets.example.com');
// → "https://assets.example.com/dist/sets/doteye/images/39.png"
<img src={createAvatar(doteye, { seed: userId }).toUrl()} alt="avatar" />

Node.js / SSR

import { createAvatar, doteye } from 'quick-avatar';

const avatar = createAvatar(doteye, { seed: '[email protected]' });

// Read as Buffer (e.g. for HTTP response or sharp processing)
const buffer = avatar.toBuffer();
res.setHeader('Content-Type', 'image/png');
res.end(buffer);

// Or get the absolute file path
const filePath = avatar.toFilePath();
// → "/path/to/node_modules/quick-avatar/dist/sets/doteye/images/39.png"

API

createAvatar(collection, options)

| Parameter | Type | Description | |-----------|------|-------------| | collection | AvatarCollection | An imported style set, e.g. doteye | | options.seed | string | Any string — user ID, email, username, etc. | | options.cdnBase | string (optional) | Default CDN base URL used by toUrl() |

Returns an AvatarResult:

| Method / Property | Returns | Notes | |-------------------|---------|-------| | toDataUri() | Promise<string> | Lazy-loads the image as a base64 data URI | | toUrl(cdnBase?) | string | CDN URL, synchronous, zero bundle cost | | toBuffer() | Buffer | Node.js only — reads the PNG file synchronously | | toFilePath() | string | Node.js only — absolute path to the PNG file | | index | number | Which avatar was selected (0-based) | | set | string | Name of the collection, e.g. "doteye" |


Available Style Sets

| Import | Name | Count | Background | |--------|------|-------|------------| | doteye | Doteye | 64 | White | | doteyeAlpha | Doteye Alpha | 64 | Transparent | | doteyePaper | Doteye Paper | 64 | Transparent (B&W) | | ol | OL | 72 | White |

import { createAvatar, doteye, doteyeAlpha, doteyePaper, ol } from 'quick-avatar';

// Solid white background
const avatar = createAvatar(doteye, { seed: '[email protected]' });

// Transparent background — compose over any color
const avatarAlpha = createAvatar(doteyeAlpha, { seed: '[email protected]' });

// Black & white, transparent background
const avatarPaper = createAvatar(doteyePaper, { seed: '[email protected]' });

Bundle Size

quick-avatar uses code splitting so your bundle only ever includes the image chunks you actually render:

  • Core logic (index.mjs): ~5 KB
  • Per-image chunk: ~40–100 KB, loaded on demand
  • CDN mode: 0 KB — images are fetched at runtime, never bundled

Adding a New Style Set

1. Add PNG files

Place your images in avatars/<setName>/. File names can be anything — they will be sorted numerically and assigned 0-based indices.

avatars/
  pixel/
    pixel-avatar-1.png
    pixel-avatar-2.png
    ...

2. Run the generate script

npm run generate pixel
# or regenerate all sets at once:
npm run generate

This will:

  • Convert each PNG to a base64 module in src/sets/pixel/images/*.ts
  • Write a src/sets/pixel/meta.ts with the count and set name
  • Copy the original PNG files to dist/sets/pixel/images/ for CDN use

3. Create the collection file

Create src/sets/pixel/index.ts:

import { resolve } from 'path';
import { fileURLToPath } from 'url';
import type { AvatarCollection } from '../../core/types.js';
import { count, name } from './meta.js';

const __dirname = fileURLToPath(new URL('.', import.meta.url));

export const pixel: AvatarCollection = {
  name,
  count,

  async getImage(index: number): Promise<string> {
    const mod = await import(`./images/${index}.ts`);
    return mod.default as string;
  },

  getFilePath(index: number): string {
    return resolve(__dirname, 'sets', name, 'images', `${index}.png`);
  },
};

4. Export from the main entry

Add one line to src/index.ts:

export { createAvatar } from './core/create-avatar.js';
export type { AvatarCollection, AvatarOptions, AvatarResult } from './core/types.js';

export { doteye } from './sets/doteye/index.js';
export { pixel } from './sets/pixel/index.js';  // ← add this

5. Build

npm run build

Users can now import the new set:

import { createAvatar, pixel } from 'quick-avatar';

Development

# Install dependencies
npm install

# Regenerate all sets from source PNGs
npm run generate

# Build (clean → generate → compile)
npm run build

License

MIT