Skip to content

About

Generate unique, symmetrical geometric icons from hash strings.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Geometricon

Minimal, deterministic geometric icons from hash strings. Every icon is built from a strict grid, a small glyph vocabulary, and a 3-color palette derived from the hash — so the whole set reads as one designed system. Same hash, same icon, every time.

Styles

Quad (default)

A 2×2 grid of quarter-disc glyphs arranged in a curated motif (bloom, pinwheel, focus, or wave), with one hash-picked cell swapped for a circle, solid, or gap.

Orbit

One primary disc plus a single accent element — a corner petal, edge half-disc, satellite dot, ring, or horizon band. The most minimal of the three; best for decorative marks. For large user sets where per-hash distinctness matters most, prefer mosaic.

Mosaic

A 3×3 grid mirrored across the vertical axis — classic identicon DNA rebuilt with the quarter-disc vocabulary. The most distinctive per-hash, good for avatars.

Tiles

Icons sit on a rounded tile by default; circle and none are also available.

Rounded (default) Circle None

Features

  • Deterministic: same hash always produces the same icon
  • Three minimal styles (quad, orbit, mosaic) plus the original classic generator
  • Generate from raw text (generateIconFromText) — no hashing required on your side
  • Light and dark palette variants that pair with your site's theme
  • Per-icon 3-color palette (tile, ink, accent) derived from the hash — solid fills, no opacity mush
  • hue / hueRange lock so a whole icon set harmonizes with your site palette
  • Rounded-tile, circle, or transparent backgrounds; full-bleed padding for avatars
  • Dual ESM/CJS build, pure TypeScript with no dependencies, clean SVG output

Installation

npm install geometricon

Or from a checkout: npm install && npm run build.

Usage

CLI Usage

# Default: quad style, light variant, rounded tile
geometricon abc123def456 -o icon.svg

# Generate straight from text — hashed internally
geometricon --text "cj@gdws.co" -o avatar.svg

# Pick a style
geometricon abc123 --style orbit -o orbit.svg
geometricon abc123 --style mosaic -o mosaic.svg

# Dark variant for dark UIs
geometricon abc123 --variant dark -o dark.svg

# Circle tile or no tile
geometricon abc123 --tile circle -o round.svg
geometricon abc123 --tile none -o bare.svg

# Bring your own palette: background, ink, accent
geometricon abc123 --color-palette "#F6F1EB,#2D2A26,#E2725B" -o branded.svg

# Lock the hue to your site palette (whole set stays harmonious)
geometricon abc123 --hue 220 -o brand-blue.svg
geometricon abc123 --hue-range 200,260 -o blue-family.svg

# Full-bleed avatar (no inner padding)
geometricon --text "alice" --padding 0 --tile circle -o alice.svg

# Original multi-shape generator
geometricon abc123 --style classic --composition radial --color-scheme ocean -o classic.svg

Run geometricon --help for full documentation.

Node.js API

// ESM
import { generateIcon, generateIconFromText } from 'geometricon';
// CJS
const { generateIcon, generateIconFromText } = require('geometricon');

// The easy path: any string, hashed internally
const svg = generateIconFromText('user@example.com');

// Or bring your own hash (MD5, SHA-256, any hex string)
const svg2 = generateIcon(hash, {
  style: 'orbit',        // 'quad' | 'orbit' | 'mosaic' | 'classic'
  variant: 'dark',       // 'light' | 'dark'
  tile: 'circle',        // 'rounded' | 'circle' | 'none'
  size: 96
});

// Harmonize a whole set with your site palette
const svg3 = generateIconFromText('alice', { hueRange: [200, 260] });

// Full-bleed avatar, fixed brand palette [background, ink, accent]
const svg4 = generateIconFromText('bob', {
  padding: 0,
  colorPalette: ['#F6F1EB', '#2D2A26', '#E2725B']
});

Inline the returned SVG string directly into your HTML — ids are namespaced per hash and option set, so many icons can share a page.

API Reference

generateIcon(hash: string, options?: IconOptions): string

Generates an SVG icon from a hash string.

Options (minimal styles):

Option Type Default Description
style string 'quad' 'quad', 'orbit', 'mosaic', or 'classic'
variant string 'light' 'light' or 'dark' palette
tile string 'rounded' Tile behind the mark: 'rounded', 'circle', 'none'
size number 200 Rendered width/height in pixels
hue number — Lock the palette's base hue (0-360)
hueRange [number, number] — Map the hash into a hue range; max may exceed 360 to wrap (e.g. [320, 400]). The accent may sit outside the range by design — it contrasts against the locked base
padding number 16 Inner padding of the mark inside the tile for quad/mosaic (0-30); 0 = full-bleed, good for avatars
colorPalette string[] — Fixed 3-color palette [background, ink, accent]; overrides hash-derived colors
backgroundColor string | null — Override tile color; null renders no tile

Returns: SVG string

generateIconFromText(text: string, options?: IconOptions): string

Same as generateIcon, but takes any raw string (a name, email, user id) and hashes it internally with FNV-1a. Also exported: textToHash(text) if you want the hex string itself.

generateIconData(hash: string, options?: IconOptions): IconData

Generates the classic style's data structure without rendering to SVG. Returns { backgroundColor, shapes, size }.

Classic Style

style: 'classic' preserves the original multi-shape generator with its full option set:

Option Type Default Description
shapeCount number 7 Fixed number of shapes (also shapeCountMin/shapeCountMax)
allowedShapes string[] all 'circle', 'square', 'triangle', 'hexagon', 'diamond'
composition string 'centered' 'centered', 'radial', 'split', 'frame', 'random'
color string — Single fixed color for all shapes
colorScheme string — 'pastel', 'vibrant', 'warm', 'cool', 'monochrome', 'earth', 'ocean', 'sunset'
saturationMin/Max number 40 / 65 HSL saturation range for generated colors
lightnessMin/Max number 70 / 88 HSL lightness range
opacityMin/Max number 0.75 / 0.95 Shape opacity range
useGradients boolean false Linear/radial gradients instead of solid fills

Classic example

How It Works

  1. Takes any hash string (MD5, SHA256, or any hex string) and reads bytes from it deterministically
  2. Derives a base hue, then builds a 3-color palette: a tinted tile, a deep ink of the same hue, and an accent at a harmonious hue shift (complementary, analogous, or monochrome)
  3. Picks a composition from a curated set — motif orientation, color pattern, and one "twist" cell in quad; disc + accent element in orbit; mirrored cell grid in mosaic
  4. Renders solid-fill glyphs snapped to the grid, clipped to the tile shape

Variation comes from arrangement, not randomness: every icon uses the same grid, glyph vocabulary, and palette logic, so any set of icons reads as one family.

Development

npm run build   # dual ESM/CJS build into dist/
npm test        # node:test suite, including golden-file snapshots

Determinism is the core promise: golden fixtures in test/fixtures/ pin the exact SVG output for a set of inputs. If a change intentionally alters output, regenerate them with node scripts/generate-fixtures.js — and know that every existing user's icons change with it.

About

Generate unique, symmetrical geometric icons from hash strings.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages