DOCUMENTATION

Everything you need to use Pxlkit — MIT React UI code + source-available icon packs

54 components · PixelToast guide · 211 icons across 6 packs · 3D Parallax

Getting Started

Pxlkit combines MIT-licensed React UI code with source-available pixel art icon packs. It ships with 54 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.

Install
npm install @pxlkit/core @pxlkit/gamification @pxlkit/feedback @pxlkit/social @pxlkit/weather @pxlkit/ui @pxlkit/effects
Basic Usage
import { 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>
  );
}
gamification
feedback
social
weather
mono
color prop

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

Install a single pack
npm install @pxlkit/core @pxlkit/social

Icon 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).

PxlKitData Type
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
}
Example Icon Definition
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 with Opacity
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.

Utility Functions
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.

Props
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.

AnimatedPxlKitData Type
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';
AnimatedPxlKitIcon Props
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;
}
Basic Usage
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" />
Trigger Modes
// '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" />
Speed & FPS Control
// 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} />
Export as Animated SVG
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

Parallax 3D Icons

The @pxlkit/parallax pack introduces multi-layer 3D parallax pixel icons — interactive depth-based icons where each layer floats at a different Z-depth. Mouse movement across the viewport rotates the entire scene, creating a true 3D effect. Click interactions trigger particle bursts, layer explosions, and color shifts.

Install
npm install @pxlkit/core @pxlkit/parallax
Basic Usage
import { ParallaxPxlKitIcon } from '@pxlkit/core';
import { GhostFriend, CoolEmoji } from '@pxlkit/parallax';

// Basic 3D parallax icon
<ParallaxPxlKitIcon icon={GhostFriend} size={64} colorful />

// Large interactive icon with custom strength
<ParallaxPxlKitIcon
  icon={CoolEmoji}
  size={128}
  strength={20}
  interactive
  colorful
/>

How it works: Each parallax icon is composed of multiple animated layers stacked at different Z-depths using CSS perspective + preserve-3d + per-layer translateZ. The component tracks mouse position across the entire viewport and applies rotateX/rotateY transforms to the scene with smooth lerp interpolation.

ParallaxPxlKitData Type
interface ParallaxPxlKitData {
  name: string;              // kebab-case identifier
  size: GridSize;            // grid dimensions (e.g. 16)
  category: string;          // always 'parallax'
  layers: ParallaxLayer[];   // ordered back→front (first = deepest)
  tags: string[];            // searchable tags
  author?: string;
}

interface ParallaxLayer {
  icon: AnimatedPxlKitData;  // each layer is an animated icon
  depth: number;             // Z-depth: positive = far, negative = near
  // depth: 3.0  → far background (shadow, trail)
  // depth: 0    → center baseline (body)
  // depth: -2.0 → near foreground (face details, blush)
}
ParallaxPxlKitIcon Props
interface ParallaxPxlKitProps {
  icon: ParallaxPxlKitData;   // The parallax icon data (required)
  size?: number;               // Container size in px (default: 64)
  strength?: number;           // Mouse reaction intensity (default: 18)
  colorful?: boolean;          // Full color mode (default: true)
  smoothing?: number;          // Lerp factor 0–1 (default: 0.06)
  perspective?: number;        // CSS perspective in px (default: max(200, size×2.5))
  layerGap?: number;           // Z spacing between layers (default: max(12, size×0.2))
  shadow?: boolean;            // Depth shadow between layers (default: true)
  interactive?: boolean;       // Click effects enabled (default: true)
  onActivate?: (active: boolean) => void;  // Click toggle callback
  className?: string;
  style?: React.CSSProperties;
  'aria-label'?: string;
}

Key features:

  • True 3D Depth — CSS perspective + preserve-3d + per-layer translateZ for real depth
  • Page-Wide Tracking — Mouse rotation works across the entire viewport, not just the icon
  • Click Interactions — Particle bursts, layer explosions, random rotation jolt, color hue-shift on click
  • Animated Layers — Each layer is a full AnimatedPxlKitData with frame-based animation (e.g., blinking eyes, flickering shadows)
  • Peel-Apart Intro — Layers spread out in a dramatic animation on mount
  • Depth Shadows — Soft CSS shadows between layers for visual depth
Example: GhostFriend Layers
// GhostFriend has 5 animated layers at different depths:
const GhostFriend: ParallaxPxlKitData = {
  name: 'ghost-friend',
  size: 16,
  category: 'parallax',
  layers: [
    { icon: GhostShadow, depth: 3.0 },   // far background shadow
    { icon: GhostTrail,  depth: 1.5 },   // wispy trail behind
    { icon: GhostBody,   depth: 0 },     // main body (center)
    { icon: GhostFace,   depth: -1.0 },  // eyes + mouth (closer)
    { icon: GhostBlush,  depth: -2.0 },  // blush cheeks (nearest)
  ],
  tags: ['ghost', 'cute', 'friendly', '3d', 'parallax'],
};
Available Icons ({ParallaxPack.length})
import { ParallaxPack } from '@pxlkit/parallax';
import {
  CoolEmoji,     // Sunglasses emoji with sparkle layers
  PixelHeart,    // Beating heart with glow + particles
  RetroTV,       // CRT monitor with scan lines
  PixelRocket,   // Rocket ship with exhaust + stars
  GhostFriend,   // Cute ghost with blush + trail
  NeonSkull,     // Glowing skull with neon effects
  MagicOrb,      // Floating orb with energy rings
  PixelCrown,    // Crown with sparkles
  RetroJoystick, // Gamepad with button highlights
  CyberEye,      // Cyberpunk eye with scan effects
} from '@pxlkit/parallax';

GhostFriend

CoolEmoji

LIVE 3D PREVIEW

10 parallax icons

move mouse to rotate · click to interact

UI KIT PARALLAX COMPONENTS

The UI Kit also includes scroll-based and cursor-tracking parallax wrapper components:PixelParallaxLayer (scroll-based), PixelParallaxGroup (clipped container), and PixelMouseParallax (cursor-tracking). See the UI Kit Parallax docs for details.

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.

Quick Usage
import { useToast } from '@/components/ToastProvider';
import { PixelButton } from '@pxlkit/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:

Generate SVG
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,
});
Other Utilities
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:

AI Prompt Template
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:

Parse AI Output
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 54 production-ready components: buttons, inputs, cards, selects, modals, toasts, tables, badges, avatars, skeletons, layout primitives, and animation wrappers.

UI Kit Route
/ui-kit#getting-started
Install UI Kit
npm install @pxlkit/core @pxlkit/ui-kit tailwindcss
CSS Setup (Tailwind v4)
/* Add this to your global stylesheet (e.g., globals.css or index.css) */
@import "tailwindcss";
@import "@pxlkit/ui-kit/styles.css";

/* Tell Tailwind to scan the package for its utility classes */
@source "../node_modules/@pxlkit/ui-kit";
Import Components
import { PixelButton, PixelCard, PixelInput, PixelSelect } from '@pxlkit/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.

Open Full UI Kit Documentation →

Contributing

Pxlkit is community-driven, with MIT code packages and source-available asset packs. 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:

Pack 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.ts
Pack index.ts
import 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.