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

touchgrass-avatar

v0.1.0

Published

Pixel art avatar system. 32M+ unique characters from a 7-char hex DNA string.

Downloads

87

Readme

@touchgrass/avatar

Pixel-art avatar system for touchgrass.sh. Each avatar is encoded as a 7-character hex DNA string (~32M combinations) that deterministically renders a unique character with hat, eyes, mouth, body, legs, and two independent color hues.

Install

npm install @touchgrass/avatar
# or
bun add @touchgrass/avatar

Usage

Core (framework-agnostic)

import {
  generateRandomDNA,
  decodeDNA,
  encodeDNA,
  generateGrid,
  traitsFromName,
  renderSVG,
  renderTerminal,
  renderTerminalSmall,
  hslToRgb,
  SLOTS,
  EYES, MOUTHS, HATS, BODIES, LEGS,
} from '@touchgrass/avatar';

Generate a random avatar

const dna = generateRandomDNA(); // e.g. "0a3f201"

Decode / encode DNA

const traits = decodeDNA('0a3f201');
// { eyes: 0, mouth: 2, hat: 5, body: 1, legs: 3, faceHue: 8, hatHue: 2 }

const dna = encodeDNA(traits); // "0a3f201"

Derive avatar from a name (no DNA needed)

const traits = traitsFromName('my-agent');
// Deterministic — same name always produces same traits

Render to SVG string

const svg = renderSVG('0a3f201');           // default 10px per pixel
const svg = renderSVG('0a3f201', 20);       // 20px per pixel
const svg = renderSVG('0a3f201', 10, 1);    // walking frame 1

Returns a complete <svg> string with transparent background. Use it as innerHTML, write to a .svg file, or embed in an <img> via data URI.

Render to terminal (ANSI)

const ansi = renderTerminal('0a3f201');      // full size (██ per pixel)
const ansi = renderTerminalSmall('0a3f201'); // compact (half-block ▀▄)

console.log(ansi);

Generate the pixel grid directly

const grid = generateGrid(traits, walkFrame, talkFrame, waveFrame);
// Pixel[][] — 9 columns wide, variable rows tall

Svelte

<script>
  import { Avatar } from '@touchgrass/avatar/svelte';
</script>

<!-- From DNA string -->
<Avatar dna="0a3f201" />

<!-- From name (deterministic hash) -->
<Avatar name="my-agent" />

<!-- Sizes: sm (3px), lg (8px, default), xl (14px) -->
<Avatar dna="0a3f201" size="xl" />

<!-- Animations -->
<Avatar dna="0a3f201" walking />
<Avatar dna="0a3f201" talking />
<Avatar dna="0a3f201" waving />

Props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | dna | string | — | 7-char hex DNA string | | name | string | — | Fallback: derive traits from name hash | | size | 'sm' \| 'lg' \| 'xl' | 'lg' | Pixel size (3/8/14px per cell) | | walking | boolean | false | Animate legs | | talking | boolean | false | Animate mouth | | waving | boolean | false | Animate arms |

Either dna or name should be provided. If both are set, dna takes priority.

DNA Encoding

7 traits packed into a single integer using mixed-radix encoding with fixed slot sizes for forward compatibility:

| Trait | Variants | Slot size | Description | |-------|----------|-----------|-------------| | eyes | 11 | 12 | normal, wide, close, big, squint, narrow, etc. | | mouths | 7 | 12 | smile, smirk, narrow, wide variants | | hats | 24 | 24 | none, tophat, beanie, crown, cap, horns, mohawk, etc. | | bodies | 6 | 8 | normal, narrow, tapered (each with/without arms) | | legs | 6 | 8 | biped, quad, tentacles, thin, wide stance | | faceHue | 12 | 12 | 0-330 degrees in 30-degree steps | | hatHue | 12 | 12 | independent from face hue |

Total slot space: 12 x 12 x 24 x 8 x 8 x 12 x 12 = 31,850,496 (~32M, 7 hex chars).

New variants can be added within slot limits without breaking existing DNA strings. Legacy 6-char DNAs decode identically (leading zero is implicit).

Pixel Grid

The avatar is a 9-column grid with variable height (depends on hat). Each cell is a Pixel type:

| Pixel | Meaning | Rendering | |-------|---------|-----------| | f | Face/body | Solid face color | | e | Eye | Solid dark color | | s | Squint eye | Face bg + dark bottom half | | n | Narrow eye | Face bg + dark center strip | | m | Mouth | Face bg + dark top half | | q | Smile corner left | Face bg + dark bottom-right quarter | | r | Smile corner right | Face bg + dark bottom-left quarter | | d | Dark accent | Solid dark (hat bands, etc.) | | h | Hat | Solid hat color | | l | Thin leg | Half-width face color | | k | Thin hat detail | Half-width hat color | | a | Arm | Half-height face color | | _ | Transparent | Empty |

Colors

Each avatar has 3 colors derived from two hue indices (0-11, mapped to 0-330 degrees):

  • Face color: hsl(faceHue * 30, 50%, 50%)
  • Dark color: hsl(faceHue * 30, 50%, 28%) — eyes, mouth
  • Hat color: hsl(hatHue * 30, 50%, 50%)

Animations

The grid generator supports three animation types via frame parameters:

  • Walking (frame): Cycles through leg variant frames
  • Talking (talkFrame): 0 = normal mouth, 1+ = open mouth animation
  • Waving (waveFrame): 0 = normal body, 1+ = alternating arm positions

Exports

@touchgrass/avatar          — Core TypeScript (DNA, grid, SVG, terminal, colors)
@touchgrass/avatar/svelte   — Svelte 5 component (Avatar)

License

MIT