iconoma-icons
v1.0.0
Published
Deterministic SVG icon generator. Give it a string, get back a unique icon.
Maintainers
Readme
Iconoma
Deterministic SVG icon generator. Give it a string, get back a unique icon. Same string → same icon, every time. Zero runtime dependencies.
Perfect for user avatars, wallet identicons, placeholder images, or anywhere you need a unique visual identity from a string.
Table of Contents
- Install
- Quick Start
- Real-World Examples
- Styles
- Color Palettes
- Options Reference
- Style Parameters
- Creating Custom Styles
- Packages
- License
Install
npm install @iconoma-icons/core @iconoma-icons/collectionQuick Start
Two choices: pick a style, pick a palette. That's it.
import { createIcon } from '@iconoma-icons/core';
import { pixel } from '@iconoma-icons/collection';
import { palettes } from '@iconoma-icons/collection';
const icon = createIcon(pixel, {
seed: '[email protected]',
colors: palettes.ocean,
});
// Raw SVG string
icon.toString();
// Data URI for <img src="...">
icon.toDataUri();Every unique seed produces a unique icon. Same seed always produces the exact same icon.
Real-World Examples
User Avatars — Every User Gets a Unique Icon
Use any unique identifier as the seed — user ID, email, username. Every user automatically gets a consistent, unique avatar.
// React component
import { createIcon } from '@iconoma-icons/core';
import { pixelated } from '@iconoma-icons/collection';
import { palettes } from '@iconoma-icons/collection';
function UserAvatar({ userId, size = 48 }) {
const icon = createIcon(pixelated, {
seed: userId,
size,
colors: palettes.candy,
isCircle: true,
});
return <img src={icon.toDataUri()} alt="avatar" width={size} height={size} />;
}
// Usage — each user automatically gets their own icon
<UserAvatar userId="user_abc123" />
<UserAvatar userId="user_def456" />
<UserAvatar userId="user_ghi789" />Web3 Wallet Icons — One Icon Per Address
Every wallet address gets a unique, deterministic icon. Users can recognize their wallets visually.
import { createIcon } from '@iconoma-icons/core';
import { mosaic } from '@iconoma-icons/collection';
import { palettes } from '@iconoma-icons/collection';
function getWalletIcon(address) {
return createIcon(mosaic, {
seed: address,
size: 64,
colors: palettes.neon,
isCircle: true,
});
}
// Every address gets its own unique icon
const icon1 = getWalletIcon('0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18');
const icon2 = getWalletIcon('0x8Ba1f109551bD432803012645Ac136ddd64DBA72');
// Same address always gives the same icon
getWalletIcon('0x742d...').toString() === getWalletIcon('0x742d...').toString(); // trueChat App — Avatars for Everyone in a Room
function ChatRoom({ messages }) {
return (
<div>
{messages.map(msg => {
const avatar = createIcon(inkblot, {
seed: msg.authorId,
size: 32,
colors: palettes.sunset,
isCircle: true,
});
return (
<div key={msg.id} className="message">
<img src={avatar.toDataUri()} className="avatar" />
<span>{msg.text}</span>
</div>
);
})}
</div>
);
}Node.js — Generate Icons Server-Side
import fs from 'fs';
import { createIcon } from '@iconoma-icons/core';
import { waves } from '@iconoma-icons/collection';
import { palettes } from '@iconoma-icons/collection';
// Generate and save to file
const icon = createIcon(waves, {
seed: 'project-banner',
size: 512,
colors: palettes.forest,
});
fs.writeFileSync('banner.svg', icon.toString());Styles
8 built-in styles. Import the one you want from @iconoma-icons/collection.
import {
pixel, pixelated, mondrian, gradient,
mosaic, waves, polycon, inkblot
} from '@iconoma-icons/collection';Color Palettes
8 built-in palettes. Each is an array of 5 hex color strings.
import { palettes } from '@iconoma-icons/collection';
// Use any palette
createIcon(pixel, { seed: 'demo', colors: palettes.ocean });
createIcon(waves, { seed: 'demo', colors: palettes.candy });| Palette | Colors |
|---------|--------|
| neon (default) | #FF006E #8338EC #3A86FF #FFBE0B #FB5607 |
| sunset | #FF6B6B #FF8E53 #FFC857 #E85D75 #4A1942 |
| ocean | #0077B6 #00B4D8 #90E0EF #023E8A #CAF0F8 |
| forest | #2D6A4F #40916C #74C69D #1B4332 #D8F3DC |
| pastel | #FFB5A7 #FCD5CE #F8EDEB #F9DCC4 #FEC89A |
| earth | #BC6C25 #DDA15E #606C38 #283618 #FEFAE0 |
| mono | #F8F9FA #DEE2E6 #ADB5BD #495057 #212529 |
| candy | #F72585 #7209B7 #3A0CA3 #4361EE #4CC9F0 |
You can also pass your own colors — just use an array of 3-5 hex strings:
createIcon(pixel, {
seed: 'custom',
colors: ['#1a1a2e', '#16213e', '#0f3460', '#e94560', '#533483'],
});Options Reference
createIcon(style, {
seed: 'any-string', // Determines the output — same seed = same icon
size: 128, // Width & height in px
colors: palettes.neon, // Array of 3-5 hex strings (e.g. '#FF006E')
isCircle: true, // Clip to circle
borderRadius: 20, // Rounded corners (ignored if isCircle is true)
styleOptions: { ... }, // Fine-tune the style (see below)
});All options are optional. If you pass nothing, you get a random icon at 128px with the neon palette.
Style Parameters
Each style has tunable parameters via styleOptions. These are optional — defaults work well without them.
pixel (Blocky)
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| seedDensity | number | 0.3–0.6 | 0.45 | Initial cell population density |
| generations | number | 2–5 | 3 | Cellular automaton iterations |
| maxCells | number | 12–20 | 15 | Max cells (rejects too-dense results) |
| marginSize | number | 0.1–0.2 | 0.15 | Margin around figure |
pixelated
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| blockSize | number | 4–16 | 8 | Size of each pixel block |
| patternType | string | — | 'random' | 'random' | 'diagonal' | 'concentric' | 'scattered' | 'clustered' |
| colorVariation | number | 0–1 | 0.5 | Color variance between blocks |
| colorsPerIcon | number | 2–5 | 4 | Palette colors used |
mondrian
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| divisionCount | number | 4–20 | 10 | Number of rectangular divisions |
| lineThickness | number | 1–8 | 3 | Dividing line width in px |
| balance | number | 0–1 | 0.5 | 0 = structured, 1 = random layout |
| colorsPerIcon | number | 2–5 | 4 | Palette colors used |
gradient
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| waveComplexity | number | 1–5 | 3 | Number of color stops |
| direction | string | — | 'diagonal' | 'horizontal' | 'vertical' | 'diagonal' | 'radial' | 'randomize' |
| blendSmoothness | number | 0–1 | 0.7 | Transition smoothness |
mosaic
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| tileCount | number | 20–200 | 80 | Number of Voronoi tiles |
| tileSizeVariation | number | 0–1 | 0.5 | Tile size uniformity |
| gapSize | number | 0–4 | 1 | Gap between tiles in px |
| colorsPerIcon | number | 2–5 | 4 | Palette colors used |
waves
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| waveCount | number | 1–8 | 4 | Number of wave layers |
| amplitude | number | 0.1–0.5 | 0.25 | Wave height (proportion of canvas) |
| frequency | number | 1–8 | 3 | Wave cycles across canvas |
| direction | string | — | 'horizontal' | 'horizontal' | 'vertical' | 'diagonal' | 'radial' | 'randomize' |
polycon
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| gridSize | number | 2–4 | 2 | Grid dimensions (2×2, 3×3, 4×4) |
| emptyProbability | number | 0–1 | 0.15 | Chance cell is blank |
| fullSquareProbability | number | 0–1 | 0.10 | Chance cell is full square vs triangle |
| colorsPerIcon | number | 2–5 | 3 | Palette colors used |
inkblot
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| blobCount | number | 1–6 | 3 | Number of blob shapes |
| spread | number | 0.2–0.8 | 0.5 | How far blobs spread from center |
| symmetry | string | — | 'vertical' | 'none' | 'horizontal' | 'vertical' | 'both' |
| centered | boolean | — | false | Center blobs vs allow offset |
Creating Custom Styles
See the @iconoma-icons/core README for how to write your own style functions.
Packages
| Package | Description |
|---------|-------------|
| @iconoma-icons/core | Engine — createIcon(), SeededRandom, types |
| @iconoma-icons/collection | 8 styles + 8 color palettes |
