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

@omindud/pixel-404

v1.0.0

Published

The Lost Games Library - A retro pixel-art CRT arcade widget for web 404 pages

Downloads

190

Readme

pixel-404 ("The Lost Games Library")

A drop-in, brand-adaptive retro pixel-art arcade widget designed specifically for web 404 error pages. Sleek Game Box frame, 12 retro theme presets, full game customization for all 8 minigames, responsive layouts (Box, Fullscreen, Compact, Borderless), transparent background inheritance, procedural Web Audio sound effects, and persistent navigation back to your main website.

License: MIT Bundle Size Zero Dependencies TypeScript: Strict


Highlights & Customization Power

  1. 🎨 12 Curated Retro Theme Presets & Deep Custom Tokens:
    • Instant 1-line themes: 'arcade-neon', 'cyberpunk', 'matrix', 'gameboy', 'dracula', 'synthwave', 'retro-amber', 'monochrome', 'nord', 'solarized-dark', 'vaporwave', 'minimal-light'.
    • Override any color token (primaryColor, accentColor, secondaryColor, viewportBackgroundColor, borderColor, glow, crt scanlines) to match your brand down to the pixel.
  2. 📐 4 Layout Presentation Modes:
    • 'box' (Default framed arcade cabinet card).
    • 'fullscreen' (Immersive retro console filling 100vw / 100vh).
    • 'compact' (Streamlined widget for sidebars, modals, or split grids).
    • 'borderless' (Clean unframed embed inheriting parent container CSS).
  3. 🏷️ Full 404 Page Branding & Navigation:
    • Customizable error codes (errorCode: '404'), custom titles, subtitles, and status badges (statusBadgeText: 'STATUS: 404 NOT FOUND').
    • Primary "Return to Home" CTA + flexible secondaryActions (e.g. Documentation, Status Page, Contact Support).
  4. 🕹️ Deep Customization for Every Minigame:
    • Error Runner: 5 characters (dino, mario, bot, cat, ghost), 5 environments, custom speeds, jump forces, and obstacle error labels.
    • Data Snake: Custom speeds, acceleration, border wall wrapping toggle, custom food & bonus labels ('404', '200'), and custom palette.
    • Error Breakout: Paddle width & speed, ball velocity, lives, custom brick dimensions, custom HTTP error codes (['404', 'ERR', '500', 'FAIL']), and brick durability.
    • Flappy Packet: Firewall cable gaps, scroll speeds, cable widths, custom packet labels ('404', 'TCP'), and stream characters.
    • Stack Overflow: Block dimensions, moving speeds, speed curve per layer, perfect drop tolerance, and bonus points.
    • Whack-a-Bug: Session duration, spawn intervals, custom terminal key labels, custom bug types (bug, error404, glitch, patch), and colors.
    • Packet Crosser: Traffic speed multipliers, lives, custom traffic lane obstacles (DDOS, BOT, HTTP), and server destination ports (:80, :443, :8080).
    • Arcade Carousel: Filter allowed games, custom titles, badges, and high score toggles.
  5. 🔊 Master Volume & Procedural 8-Bit Web Audio:
    • Pure native AudioContext with master volume control (masterVolume: 0.0 to 1.0) — 0 external audio asset downloads!
  6. 📱 Unified Touch Controls & Key Bindings:
    • Responsive virtual D-pad and Action buttons automatically appear on mobile devices or touchscreens.
    • Rebind keyboard controls to custom key sets via controls.keyBindings.
  7. ⚡ Fast & Direct Single-Game Boot:
    • Boot straight into any game without menus (game: 'runner'), or choose game: 'random' to surprise visitors with a new game on each 404 hit.

Installation

npm install pixel-404
# or
yarn add pixel-404
# or
pnpm add pixel-404

Quickstart

1. React & Next.js (App Router)

// app/not-found.tsx
'use client';

import { PixelArcade } from 'pixel-404/react';

export default function NotFound() {
  return (
    <main style={{
      minHeight: '100vh',
      display: 'grid',
      gridTemplateColumns: '1fr 1.1fr',
      alignItems: 'center',
      padding: '40px',
      background: 'radial-gradient(circle at 20% 30%, #1e1b4b 0%, #030712 80%)',
    }}>
      {/* Left: Your Custom Website 404 Headline */}
      <div>
        <span style={{ color: '#00ffaa', fontFamily: 'monospace' }}>STATUS: 404 NOT FOUND</span>
        <h1 style={{ fontSize: '72px', color: '#fff', margin: '8px 0' }}>404</h1>
        <h2>Whoops! Page lost in cyberspace.</h2>
        <p style={{ color: '#94a3b8', maxWidth: '420px', lineHeight: 1.6 }}>
          The requested route was not found on this server. While we reboot the edge node, jump over 404 firewalls to escape!
        </p>
        <a href="/" style={{ color: '#00ffaa', marginTop: '16px', display: 'inline-block', fontWeight: 'bold' }}>
          ← Return to Main Site
        </a>
      </div>

      {/* Right: Embedded Game Box */}
      <PixelArcade
        game="runner"
        runner={{
          character: 'dino',                  // 'dino' | 'mario' | 'bot' | 'cat' | 'ghost'
          environment: 'retro-desert',        // 'cyber' | 'retro-desert' | 'matrix' | 'space' | 'minimal'
          baseSpeed: 6.5,
          obstacleTexts: ['404', '500', 'TIMEOUT', 'NULL'],
        }}
        theme={{
          preset: 'cyberpunk',                // 12 retro presets available
          crt: true,                          // Retro CRT scanlines
          backgroundColor: 'transparent',    // Inherits site background
        }}
        brand={{
          showHeader: false,                  // Handled by your page headline
          showHomeButton: false,              // Handled by your page link
        }}
        controls={{
          sound: true,
          masterVolume: 0.4,
          touchControls: 'auto',
        }}
      />
    </main>
  );
}

2. Plain HTML / Vanilla JavaScript

<div id="game-container" style="max-width: 680px; margin: 40px auto;"></div>

<script type="module">
  import { mountPixel404 } from 'pixel-404';

  const game = mountPixel404(document.getElementById('game-container'), {
    game: 'snake',
    snake: {
      speed: 8,
      wrapWalls: true,
      foodLabel: '404',
      bonusLabel: '200',
    },
    theme: {
      preset: 'matrix',
      crt: true,
    },
    brand: {
      name: 'Acme Cloud',
      title: 'ERROR 404',
      subtitle: 'Packet lost in routing table',
      homeUrl: '/',
      secondaryActions: [
        { label: 'System Status', url: 'https://status.example.com', external: true },
        { label: 'Documentation', url: '/docs' },
      ],
    },
  });

  // Dynamic Theme Switch at Runtime:
  // game.setTheme('dracula');
  
  // Cleanup on unmount / navigation:
  // game.destroy();
</script>

12 Retro Theme Presets

You can select any preset using theme.preset, or pass custom color tokens to override specific properties:

| Preset ID | Name | Primary Color | Accent Color | Aesthetic Description | |---|---|---|---|---| | 'arcade-neon' | Arcade Neon | #00ffaa (Neon Mint) | #ff0077 (Hot Pink) | High-contrast 80s arcade neon glow (Default) | | 'cyberpunk' | Cyberpunk | #00f0ff (Electric Cyan) | #ffe600 (Yellow) | Night City high-tech chrome & neon | | 'matrix' | Matrix Code | #00ff66 (Phosphor Green)| #00aa33 (Deep Green) | Digital terminal green rain | | 'gameboy' | Game Boy Classic | #8bac0f (Light Olive) | #306230 (Forest) | Authentic 4-shade 1989 handheld LCD | | 'dracula' | Dracula Gothic | #bd93f9 (Soft Purple) | #ff79c6 (Pink) | Sleek dark slate & pastel gothic palette | | 'synthwave' | Synthwave Sunset | #ff71ce (Vibrant Pink) | #01cdfe (Neon Blue) | Outrun wireframe sunset aesthetics | | 'retro-amber' | Retro Amber CRT | #ffb000 (Warm Amber) | #ff8000 (Deep Amber)| Vintage monochrome mainframe terminal | | 'monochrome' | Monochrome Clean | #ffffff (Crisp White) | #888888 (Mid Gray) | Minimalist high-contrast monochrome | | 'nord' | Nordic Frost | #88c0d0 (Frost Cyan) | #81a1c1 (Glacier) | Arctic ice blues and muted slate | | 'solarized-dark' | Solarized Dark | #2aa198 (Teal) | #b58900 (Amber) | Ethan Schoonover's precision palette | | 'vaporwave' | Vaporwave | #fca5a5 (Pastel Rose) | #38bdf8 (Sky Cyan) | Chill aesthetic nostalgic pastels | | 'minimal-light' | Minimal Light | #2563eb (Royal Blue) | #f59e0b (Amber) | Crisp, modern light mode with clean borders |

// Example: Using a preset with custom token overrides
const config = {
  theme: {
    preset: 'cyberpunk',
    crt: true,
    borderRadius: '8px',
    borderWidth: '2px',
    backgroundColor: 'transparent',
  }
};

404 Brand & Layout Options (BrandConfig)

interface BrandConfig {
  /** Layout mode: 'box' (default) | 'fullscreen' | 'compact' | 'borderless' */
  layout?: 'box' | 'fullscreen' | 'compact' | 'borderless';
  
  /** Display name of the brand or site */
  name?: string;
  
  /** URL to brand logo */
  logoUrl?: string;
  
  /** Primary 404 headline (default: '404') */
  title?: string;
  
  /** Descriptive subtitle or explanation */
  subtitle?: string;
  
  /** Error code tag (default: '404') */
  errorCode?: string;
  
  /** Custom text for status badge pill (e.g. 'STATUS: 404 NOT FOUND') */
  statusBadgeText?: string;
  
  /** Whether to show status badge (default: true) */
  showStatusBadge?: boolean;
  
  /** Destination for Return Home CTA (default: '/') */
  homeUrl?: string;
  
  /** Text for Return Home CTA (default: 'Return to Main Site') */
  homeText?: string;
  
  /** Additional secondary links (Documentation, Status, Contact) */
  secondaryActions?: Array<{
    label: string;
    url: string;
    external?: boolean;
    onClick?: () => void;
  }>;
  
  /** Render brand header inside the game box (default: true) */
  showHeader?: boolean;
  
  /** Render return home button inside the game box (default: true) */
  showHomeButton?: boolean;
  
  /** Screen aspect ratio (default: '4/3', e.g. '16/9', 'auto') */
  aspectRatio?: string;
  
  /** Max width of widget (default: '680px') */
  maxWidth?: string;
}

Minigame Configuration Reference

1. Error Runner (RunnerConfig)

runner: {
  character: 'dino',                  // 'dino' | 'mario' | 'bot' | 'cat' | 'ghost'
  environment: 'cyber',               // 'cyber' | 'retro-desert' | 'matrix' | 'space' | 'minimal'
  baseSpeed: 6.0,                     // Initial scrolling speed
  jumpForce: -440,                    // Upward velocity on jump
  gravity: 1200,                      // Gravitational pull
  groundColor: '#00ffaa',             // Custom ground track color
  obstacleTexts: ['404', 'NULL'],     // Custom text labels on ground blocks & drones
  playerSpriteUrl: 'https://...',     // Optional custom mascot image
  gameOverTitle: 'SYSTEM CRASH',      // Custom Game Over headline
}

2. Data Snake (SnakeConfig)

snake: {
  speed: 7,                           // Starting movements per second
  speedIncrease: 0.002,               // Acceleration per food consumed
  wrapWalls: true,                    // Wrap edges instead of crashing on wall hit
  foodLabel: '404',                   // Text label on standard food items
  bonusLabel: '200',                  // Text label on bonus items
  snakeColor: '#00ffaa',              // Body segments color
  snakeHeadColor: '#ffffff',          // Snake head color
  foodColor: '#ff0077',               // Food color
  bonusColor: '#f59e0b',              // Bonus item color
  gridSize: { cols: 24, rows: 16 },   // Grid dimensions
  gameOverTitle: 'BUFFER OVERFLOW',   // Custom Game Over title
}

3. Error Breakout (BreakoutConfig)

breakout: {
  ballSpeed: 220,                     // Ball velocity (pixels/sec)
  ballSize: 6,                        // Ball diameter
  ballColor: '#ffffff',               // Ball color
  paddleWidth: 56,                    // Paddle width in logical pixels
  paddleSpeed: 320,                   // Paddle keyboard speed
  lives: 3,                           // Starting lives
  brickRows: 4,                       // Number of brick rows
  brickCols: 7,                       // Number of columns
  brickTexts: ['404', 'ERR', '500'],  // Labels cycled through bricks
  brickColors: ['#ef4444', '#f59e0b'],// Palette for rows
  brickHealth: 2,                     // Max hit points per brick
  gameOverTitle: 'FIREWALL BREACH',   // Custom Game Over title
}

4. Flappy Packet (FlappyConfig)

flappy: {
  gravity: 740,                       // Downward gravity
  flapStrength: -250,                 // Upward lift velocity per tap/space
  cableGap: 84,                       // Vertical gap between top and bottom cables
  cableSpeed: 125,                    // Horizontal scroll speed
  cableWidth: 42,                     // Cable pillar width
  spawnInterval: 1.65,                // Interval between cable pairs (seconds)
  packetLabel: '404',                 // Label on winged packet
  cableColor: '#ff0077',              // Cable color
  packetColor: '#00ffaa',             // Packet color
  backgroundChars: ['0', '1', 'TCP'], // Binary background stream
  gameOverTitle: 'CONNECTION LOST',   // Custom Game Over title
}

5. Stack Overflow (StackerConfig)

stacker: {
  blockWidth: 120,                    // Starting block width
  blockHeight: 18,                    // Block layer height
  initialSpeed: 3.0,                  // Starting horizontal swing speed
  speedIncreasePerLayer: 0.15,        // Speedup per stacked block
  perfectTolerance: 5,                // Pixel margin considered a "Perfect Drop"
  blockLabel: 'STACK',                // Label text on blocks
  blockColors: ['#38bdf8', '#818cf8'],// Colors cycled per layer
  bonusPoints: 25,                    // Extra points for perfect alignment
  gameOverTitle: 'STACK OVERFLOW',    // Custom Game Over title
}

6. Whack-a-Bug (WhackConfig)

whack: {
  gameDuration: 30,                   // Session timer countdown in seconds
  spawnCooldown: 0.6,                 // Time between bug emergences
  minSpawnCooldown: 0.25,             // Minimum spawn interval in frenzy mode
  keyLabels: ['1','2','3','4','5','6','7','8','9'], // Custom slot hotkey labels
  bugTexts: {
    bug: 'BUG',                       // Normal bug label
    error404: '404',                  // 404 error target label
    glitch: 'ERR',                    // Glitch target label
    patch: 'FIX',                     // Patch bonus target label
  },
  bugColor: '#ef4444',                // Standard bug color
  glitchColor: '#a855f7',             // Glitch target color
  patchColor: '#22c55e',              // Patch target color
  gameOverTitle: 'SESSION TIMEOUT',   // Custom Game Over title
}

7. Packet Crosser (CrosserConfig)

crosser: {
  lives: 3,                           // Player packet lives
  speedMultiplier: 1.0,               // Obstacle speed multiplier
  trafficLabels: {
    trucks: ['DDOS', 'BOT', 'HTTP'],  // Lane labels
    lasers: ['ERR', 'CORRUPT'],
  },
  portLabels: [':80 HTTP', ':443 SSL', ':8080 API'], // Destination dock labels
  playerColor: '#00ffaa',             // Player packet color
  gameOverTitle: 'PACKET CORRUPTED',  // Custom Game Over title
}

8. Arcade Carousel (MenuConfig)

menu: {
  allowedGames: ['runner', 'snake', 'breakout'], // Filter selectable games
  menuTitle: 'THE LOST ARCADE',       // Header title
  showHighScores: true,               // Show high score medals
}

Audio & Controls (ControlsConfig)

controls: {
  sound: true,                        // Enable Web Audio procedural sound effects
  masterVolume: 0.5,                  // Volume: 0.0 (silent) to 1.0 (full)
  showSoundToggle: true,              // Show on-screen 🔊/🔇 button
  showRestartButton: true,            // Show on-screen ↺ button
  touchControls: 'auto',              // 'auto' | 'always' | 'never' (Mobile D-pad & Actions)
  keyBindings: {                      // Rebind keyboard controls
    jump: ['Space', 'ArrowUp', 'KeyW'],
    duck: ['ArrowDown', 'KeyS'],
    left: ['ArrowLeft', 'KeyA'],
    right: ['ArrowRight', 'KeyD'],
  },
}

Runtime Imperative API

Both Vanilla JS and React expose programmatic controls:

Vanilla JavaScript (Pixel404Instance)

const game = mountPixel404(mountEl, config);

// Change theme preset or tokens dynamically without reloading:
game.setTheme('dracula');
game.setTheme({ primaryColor: '#ff0055', crt: true });

// Update game configuration:
game.updateConfig({
  game: 'breakout',
  controls: { masterVolume: 0.2 },
});

// Restart active game:
game.restart();

// Clean up listeners, timers, and canvas contexts:
game.destroy();

React (PixelArcadeRef)

import { useRef } from 'react';
import { PixelArcade, PixelArcadeRef } from 'pixel-404/react';

export function ArcadeComponent() {
  const arcadeRef = useRef<PixelArcadeRef>(null);

  const switchTheme = () => {
    arcadeRef.current?.setTheme('cyberpunk');
  };

  return (
    <div>
      <button onClick={switchTheme}>Cyberpunk Mode</button>
      <PixelArcade ref={arcadeRef} game="runner" />
    </div>
  );
}

Demos

Run the local interactive customization playground:

npm run dev
  • Interactive Customizer Hub: http://localhost:5173/ (Test all 12 presets, 4 layout modes, 8 games, and generate live drop-in code)
  • Standalone Runner: http://localhost:5173/runner.html
  • Standalone Snake: http://localhost:5173/snake.html
  • Standalone Breakout: http://localhost:5173/breakout.html
  • Standalone Flappy: http://localhost:5173/flappy.html
  • Standalone Stacker: http://localhost:5173/stacker.html
  • Standalone Whack: http://localhost:5173/whack.html
  • Standalone Crosser: http://localhost:5173/crosser.html

License

MIT © Contributors