DOCUMENTATION
Everything you need to use Pxlkit — the open source retro React UI kit + icon library
53 components · PixelToast guide · 211 icons across 6 packs
Getting Started
Pxlkit is an open-source retro React UI kit and pixel art icon library. It ships with 53 production-ready components and 211+ hand-crafted SVG icons across 6 thematic packs. Each icon pack is a separate npm package under the @pxlkit scope.
npm install @pxlkit/core @pxlkit/gamification @pxlkit/feedback @pxlkit/social @pxlkit/weather @pxlkit/ui @pxlkit/effectsimport { PxlKitIcon } from '@pxlkit/core';
import { Trophy } from '@pxlkit/gamification';
import { CheckCircle } from '@pxlkit/feedback';
import { Heart } from '@pxlkit/social';
import { Sun } from '@pxlkit/weather';
function App() {
return (
<div>
{/* Colorful rendering */}
<PxlKitIcon icon={Trophy} size={32} colorful />
{/* Monochrome (inherits text color) */}
<PxlKitIcon icon={CheckCircle} size={32} />
{/* Custom color */}
<PxlKitIcon icon={Heart} size={48} color="#FF0000" />
</div>
);
}Available Packs
Pxlkit ships with 6 icon packs. Each pack can contain both static and animated icons. Install only the ones you need — they're fully tree-shakeable.
@pxlkit/gamification+ANIMATED
Icons for game mechanics, achievements, rewards, and RPG elements
51 icons
@pxlkit/feedback+ANIMATED
Icons for notifications, alerts, status messages, and toasts
28 icons
@pxlkit/social+ANIMATED
Icons for social media, community, and user interaction
43 icons
@pxlkit/weather+ANIMATED
Icons for weather conditions, seasons, and natural phenomena
36 icons
@pxlkit/ui+ANIMATED
Icons for interface controls, editor tools, and common actions
41 icons
@pxlkit/effects+ANIMATED
Animated visual effects — explosions, signals, particles, glows, and VFX
12 icons
npm install @pxlkit/core @pxlkit/socialIcon Format
Icons are defined using a simple, human-readable format: a grid of characters where each character maps to a color via a palette. The . character is always transparent.
This format is designed to be easy to read, write by hand, and generate with AI. Each row is a string of exactly N characters (where N matches the grid size).
interface PxlKitData {
name: string; // kebab-case identifier
size: 8 | 16 | 32; // grid dimensions (NxN)
category: string; // pack/category name
grid: string[]; // N rows of N characters each
palette: Record<string, string>; // char → hex color
tags: string[]; // searchable tags
author?: string; // attribution
}export const Trophy: PxlKitData = {
name: 'trophy',
size: 16,
category: 'gamification',
grid: [
'................',
'..GGGGGGGGGGGG..',
'.GG.YYYYYYYY.GG.',
'.G..YYYYYYYY..G.',
'.G..YYYWYYYY..G.',
'.GG.YYYYYYYY.GG.',
'..GGGGGGGGGGGG..',
'....GGGGGGGG....',
'.....GGGGGG.....',
'......GGGG......',
'......GGGG......',
'.....DDDDDD.....',
'....DDDDDDDD....',
'....BBBBBBBB....',
'...BBBBBBBBBB...',
'................',
],
palette: {
'G': '#FFD700', // Gold
'Y': '#FFF44F', // Yellow
'D': '#B8860B', // Dark gold
'B': '#8B4513', // Brown
'W': '#FFFFFF', // White
},
tags: ['trophy', 'achievement'],
};Key insight: This same format can be output by an AI model. The grid is essentially ASCII art with a legend. You can ask ChatGPT, Claude, or any LLM to generate it.
Opacity / Alpha
Each palette color supports per-pixel opacity via the #RRGGBBAA format. The last two hex digits represent the alpha channel (00 = fully transparent, FF = fully opaque).
palette: {
'A': '#FF000080', // Red at 50% opacity
'B': '#00FF00CC', // Green at 80% opacity
'C': '#0000FF', // Blue at 100% (default)
'D': '#FFD70040', // Gold at 25% opacity
}Supported hex formats:
#RGB— shorthand (expanded to #RRGGBB, fully opaque)#RRGGBB— standard 6-digit hex (fully opaque)#RRGGBBAA— 8-digit hex with alpha channel
The <PxlKitIcon /> component, SVG utilities, and Builder UI all handle opacity automatically. When generating SVG, pixels with opacity < 1 get a fill-opacity attribute.
import { parseHexColor, encodeHexColor } from '@pxlkit/core';
// Parse: extract color and opacity from hex string
const { color, opacity } = parseHexColor('#FF000080');
// color = '#FF0000', opacity = 0.502
// Encode: combine color and opacity back to hex
const hex = encodeHexColor('#FF0000', 0.5);
// hex = '#FF000080'
// If opacity is 1 (or omitted), returns 6-digit hex
const solid = encodeHexColor('#FF0000');
// solid = '#FF0000'React Component
The <PxlKitIcon /> component renders pixel art as inline SVG with shape-rendering: crispEdges to maintain sharp pixels at any scale. No blurring, no anti-aliasing.
interface PxlKitProps {
icon: PxlKitData; // Icon data (required)
size?: number; // Container size in px (default: 32)
colorful?: boolean; // Full color mode (default: false)
color?: string; // Override monochrome color
className?: string; // CSS class names
'aria-label'?: string; // Accessibility label
style?: React.CSSProperties;
}In monochrome mode (default), the icon uses currentColor, so it inherits the parent's text color. Pass colorful for full palette rendering.
Animated Icons
Animated icons extend the pixel art format with frame-based playback. Each frame shares a base palette and can optionally override individual colors. Playback behavior is controlled by the trigger prop.
interface AnimatedPxlKitData {
name: string;
size: 8 | 16 | 32;
category: string;
palette: Record<string, string>; // shared base palette across all frames
frames: AnimationFrame[]; // array of frames (in display order)
frameDuration: number; // ms per frame (e.g. 150)
loop: boolean; // @deprecated — use trigger instead
trigger?: AnimationTrigger; // controls playback behavior
tags: string[];
author?: string;
}
interface AnimationFrame {
grid: string[]; // same grid format as PxlKitData
palette?: Record<string, string>; // optional per-frame palette overrides
}
type AnimationTrigger = 'loop' | 'once' | 'hover' | 'appear' | 'ping-pong';interface AnimatedPxlKitProps {
icon: AnimatedPxlKitData;
size?: number; // size in px (default: 32)
colorful?: boolean; // full color mode (default: true)
color?: string; // override for monochrome mode
trigger?: AnimationTrigger; // override icon.trigger
speed?: number; // multiplier: 2 = 2× faster, 0.5 = half (0.1–10)
fps?: number; // fixed FPS — takes priority over speed (1–60)
playing?: boolean; // manual play/pause override
className?: string;
style?: React.CSSProperties;
'aria-label'?: string;
}import { AnimatedPxlKitIcon } from '@pxlkit/core';
import { FireSword } from '@pxlkit/gamification';
// Loop forever (default)
<AnimatedPxlKitIcon icon={FireSword} size={48} colorful />
// Monochrome loop
<AnimatedPxlKitIcon icon={FireSword} size={32} color="#00FF88" />// 'loop' — plays continuously (default)
<AnimatedPxlKitIcon icon={FireSword} trigger="loop" />
// 'once' — plays one time, stops on last frame
<AnimatedPxlKitIcon icon={FireSword} trigger="once" />
// 'hover' — plays only while the user hovers
<AnimatedPxlKitIcon icon={FireSword} trigger="hover" />
// 'appear' — plays once when it enters the viewport
<AnimatedPxlKitIcon icon={FireSword} trigger="appear" />
// 'ping-pong' — loops forward then backward alternating
<AnimatedPxlKitIcon icon={FireSword} trigger="ping-pong" />// 2× speed — double frame rate
<AnimatedPxlKitIcon icon={FireSword} speed={2} />
// Half speed
<AnimatedPxlKitIcon icon={FireSword} speed={0.5} />
// Fixed FPS — takes priority over speed and icon.frameDuration
<AnimatedPxlKitIcon icon={FireSword} fps={6} />
// Paused manually
<AnimatedPxlKitIcon icon={FireSword} playing={false} />import { generateAnimatedSvg } from '@pxlkit/core';
import { FireSword } from '@pxlkit/gamification';
// Colorful animated SVG with CSS keyframe animation
const svg = generateAnimatedSvg(FireSword);
// Monochrome animated SVG
const monoSvg = generateAnimatedSvg(FireSword, {
colorful: false,
monoColor: '#00FF88',
});loop
hover
ping-pong
LIVE PREVIEW
FireSword — 4 frames · 150ms
hover center icon to trigger it
Toast Notifications
Toast notifications are now documented as part of the UI Kit in /ui-kit#pixel-toast. The system is powered by <ToastProvider /> + useToast(), and supports tones, positions, durations, and animated icons.
import { useToast } from '@/components/ToastProvider';
import { PixelButton } from '@/components/ui-kit';
import { CheckCircle } from '@pxlkit/feedback';
function App() {
const { success } = useToast();
return (
<PixelButton tone="green"
onClick={() => success('SAVED', 'Your changes have been saved', CheckCircle)}
>
Show Toast
</PixelButton>
);
}Available tones: success, error, warning, info. Each tone has default colors and icons, but you can override them with any Pxlkit icon — including animated ones.
DETAILED UI KIT DOCS
Open the dedicated UI Kit section for interactive controls and full prop details:
Open PixelToast Docs →SVG Generation
You can generate standalone SVG files from icon data using the utility functions:
import { gridToSvg } from '@pxlkit/core';
import { Trophy } from '@pxlkit/gamification';
// Colorful SVG string
const colorSvg = gridToSvg(Trophy, { mode: 'colorful' });
// Monochrome SVG
const monoSvg = gridToSvg(Trophy, {
mode: 'monochrome',
monoColor: '#333333',
});
// With XML declaration (for standalone files)
const fileSvg = gridToSvg(Trophy, {
mode: 'colorful',
xmlDeclaration: true,
});import {
gridToPixels, // grid+palette → [{x, y, color}]
pixelsToGrid, // [{x, y, color}] → grid+palette
pixelsToSvg, // pixel array → SVG string
svgToDataUri, // SVG string → data:image/svg+xml URI
svgToBase64, // SVG string → base64 data URI
validateIconData, // validate PxlKitData
generateIconCode, // PxlKitData → TypeScript code
parseIconCode, // code string → PxlKitData
} from '@pxlkit/core';AI Generation
The grid format was specifically designed to work well with AI code generation. Here's a prompt template you can use with any LLM:
Generate a 16x16 pixel art icon in this JSON format:
{
"name": "icon-name-here",
"size": 16,
"category": "your-category",
"grid": [
"................",
// 16 rows, each with exactly 16 characters
// "." = transparent pixel
// Letters map to colors via palette
],
"palette": {
"A": "#HEX001",
"B": "#HEX002"
},
"tags": ["tag1", "tag2"]
}
Rules:
- Grid: exactly 16 rows of 16 chars
- "." is always transparent
- Use 3-6 colors max for clean pixel art
- Each non-"." character must have a palette entry
Create a [YOUR DESCRIPTION] icon.After the AI generates the code, you can paste it into the Builder to preview it, or use parseIconCode() programmatically:
import { parseIconCode, validateIconData } from '@pxlkit/core';
const aiOutput = `{ "name": "fire", ... }`;
const icon = parseIconCode(aiOutput);
if (icon) {
const errors = validateIconData(icon);
if (errors.length === 0) {
// Valid icon! Use it or save it
console.log('Icon parsed successfully:', icon.name);
}
}UI Kit Components
Pxlkit includes a full React + TypeScript component library with 53 production-ready components: buttons, inputs, cards, selects, modals, toasts, tables, badges, avatars, skeletons, layout primitives, and animation wrappers.
/ui-kit#getting-startedimport { PixelButton, PixelCard, PixelInput, PixelSelect } from '@/components/ui-kit';
import { PxlKitIcon } from '@pxlkit/core';
import { Trophy } from '@pxlkit/gamification';
<PixelButton tone="green" iconLeft={<PxlKitIcon icon={Trophy} size={16} />}>
Create Quest
</PixelButton>The UI Kit page includes live previews, props tables, and copy-ready code examples for each element. Use the sidebar to browse everything by category, includingPixelToast and animation utilities.
Contributing
Pxlkit is open source and community-driven. Here's how you can contribute:
- Add icons to existing packs — Create new icons using the Builder, copy the TypeScript code, and submit a PR
- Create new icon packs — See the section below for the pack structure
- Improve the Builder — Add new tools, improve UX, fix bugs
- Improve core utilities — Optimize SVG generation, add new export formats
- Documentation — Fix typos, add examples, improve guides
NAMING CONVENTIONS
- Icon names:
kebab-case(e.g., fire-sword) - Export names:
PascalCase(e.g., FireSword) - Pack names:
kebab-case(e.g., fantasy-rpg) - Tags: lowercase, comma-separated
- Colors: uppercase hex with # (e.g., #FF0000)
- Maximum 6 colors per icon for clarity
Creating Packs
A pack is a separate npm package under @pxlkit/. Here's the structure:
packages/your-pack/
├── src/
│ ├── icons/
│ │ ├── icon-one.ts # Individual icon files
│ │ ├── icon-two.ts
│ │ └── icon-three.ts
│ └── index.ts # Export all icons + IconPack
├── package.json
├── tsconfig.json
└── tsup.config.tsimport type { IconPack } from '@pxlkit/core';
import { IconOne } from './icons/icon-one';
import { IconTwo } from './icons/icon-two';
export { IconOne } from './icons/icon-one';
export { IconTwo } from './icons/icon-two';
export const YourPack: IconPack = {
id: 'your-pack',
name: 'Your Pack Name',
description: 'A collection of ... icons',
icons: [IconOne, IconTwo],
version: '0.1.0',
author: 'your-name',
};After creating your pack, add it to the monorepo workspaces, register it in the web app's icon registry, and submit a pull request.