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 🙏

© 2025 – Pkg Stats / Ryan Hefner

phaser-viewer

v0.1.9

Published

A Storybook-like development environment for Phaser 3 components with interactive testing

Readme


✨ Features

📦 Installation

npm install phaser-viewer
# or
yarn add phaser-viewer
# or
pnpm add phaser-viewer

🚀 Quick Start

1️⃣ Install phaser-viewer

npm install phaser-viewer

2️⃣ Create your component demo

Create a .demo.ts file alongside your component:

// src/Button.demo.ts
import { expect, delay } from 'phaser-viewer';
import { Meta, Demo } from 'phaser-viewer';
import { Button } from './Button'; // Import your component
import * as Phaser from 'phaser';

const meta = {
  component: Button,
  title: 'UI/Button',
  description: 'Interactive button component'
} as const satisfies Meta<typeof Button>;

export default meta;

interface ButtonArgs {
  x: number;
  y: number;
  text: string;
  config?: {
    color?: number;
    width?: number;
    height?: number;
  };
}

export const BasicButton: Demo<typeof meta, ButtonArgs> = {
  name: 'Basic Button',
  args: { x: 400, y: 300, text: 'Click Me!' },
  create: (scene, args) => {
    // Full type inference: args has x, y, text properties
    return new Button(scene, args.x, args.y, args.text, args.config);
  },
  play: async (_scene, component) => {
    // Full type inference: component is Button instance with all methods
    await expect(component.getText(), 'Initial text').toBe('Click Me!');
    
    // Test interaction
    component.emit('pointerdown');
    await delay(100);
    await expect(component.getText(), 'After click').toBe('Clicked!');
  }
};

3️⃣ Start the development server

npx phaser-viewer
# or add to package.json scripts:
# "phaser-viewer": "phaser-viewer"

That's it! Your Phaser component viewer will start automatically. No React setup files needed!

📁 Project Structure

your-project/
├── src/                   # Your Phaser components and demos
│   ├── Button.ts         # Button component implementation  
│   ├── Button.demo.ts    # Button component demos
│   ├── Sprite.ts         # Sprite component implementation
│   └── Sprite.demo.ts    # Sprite component demos
├── .phaser-viewer-temp/   # Hidden temp files (auto-generated)
└── package.json          # Include phaser-viewer script

🧪 Testing Your Components

Phaser Viewer includes a powerful testing API inspired by @storybook/test. Tests can be run interactively in the browser or automatically via CLI.

Interactive Testing

Test results appear in the Play Logs panel with visual feedback:

import { expect, delay } from 'phaser-viewer';

export const InteractiveButton: Demo<typeof meta, ButtonArgs> = {
  name: 'Interactive Button',
  args: { x: 400, y: 300, text: 'Test Button' },
  create: (scene, args) => {
    // Type inference: args is ButtonArgs, scene is Phaser.Scene
    return new Button(scene, args.x, args.y, args.text);
  },
  play: async (_scene, component) => {
    // Type inference: component is Button instance with all methods
    await expect(component.getText(), 'Initial text').toBe('Test Button');
    await expect(component.visible, 'Should be visible').toBe(true);
    
    // Test button click
    component.emit('pointerdown');
    await delay(100);
    await expect(component.getText(), 'After click').toBe('Clicked!');
    
    // Test multiple clicks
    component.emit('pointerdown');
    await delay(100);
    await expect(component.getText(), 'After second click').toBe('Clicked 2x');
  }
};

Automated Testing (CLI)

Run all Play functions as automated tests:

npx phaser-viewer test

Example Output:

🧪 Starting Phaser Viewer Test Runner...
🔧 Loaded user config: { filePath: './src/**/*.demo.ts' }
🎯 Play Functions: 2 passed, 1 failed
❌ Gold - TestableGold: Expected 999, but received 600

How it works:

  • Each Play function becomes a test unit
  • Expect assertions determine pass/fail status
  • Failed tests show detailed error messages
  • Tests run in headless browser environment
  • Automatic dependency installation (vitest, playwright)

⚡ Asset Loading with PreloadScene

For components that require assets (images, sounds, etc.), you can create a PreloadScene class to handle asset loading:

1️⃣ Create a PreloadScene class

// src/GoldPreloadScene.ts
import * as Phaser from 'phaser';

export class GoldPreloadScene extends Phaser.Scene {
  constructor() {
    super({ key: 'GoldPreloadScene' });
  }
  
  preload() {
    // Load all assets your component needs
    this.load.image('gold', 'img/gold.png');
    this.load.image('silver', 'img/silver.png');
    this.load.audio('coinSound', 'audio/coin.mp3');
  }
}

2️⃣ Reference the PreloadScene in your demo

// src/Gold.demo.ts
import { Meta, Demo } from 'phaser-viewer';
import { Gold } from './Gold';
import { GoldPreloadScene } from './GoldPreloadScene';
import * as Phaser from 'phaser';

const meta = {
  component: Gold,
  title: 'Sprites/Gold',
  description: 'Gold coin sprite with preloaded assets',
  preloadScene: GoldPreloadScene  // ← Add this line
} as const satisfies Meta<typeof Gold>;

export default meta;

interface GoldArgs {
  x: number;
  y: number;
}

export const BasicGold: Demo<typeof meta, GoldArgs> = {
  name: 'Basic Gold Coin',
  args: { x: 400, y: 300 },
  create: (scene, args) => {
    // Assets are already loaded and available!
    // Type inference: args has x, y properties
    return new Gold(scene, args.x, args.y);
  }
};

3️⃣ Use assets in your component

// src/Gold.ts
export class Gold extends Phaser.GameObjects.Sprite {
  constructor(scene: Phaser.Scene, x: number, y: number) {
    // The 'gold' texture is already loaded by GoldPreloadScene
    super(scene, x, y, 'gold');
    scene.add.existing(this);
    
    // You can also use other preloaded assets
    this.setInteractive();
    this.on('pointerdown', () => {
      scene.sound.play('coinSound'); // Audio is also preloaded
    });
  }
}

How it works

  1. PreloadScene starts first - Phaser Viewer automatically detects and runs your PreloadScene
  2. Assets are loaded - All assets defined in preload() method are loaded into memory
  3. ViewerScene launches - After loading completes, the viewer scene starts
  4. Assets are available - Your components can immediately use the preloaded assets

This ensures smooth component rendering without loading delays or missing asset errors.

🎛️ Scene Configuration

Phaser Viewer allows you to customize the canvas size and background color to match your project needs:

Basic Scene Configuration

// phaser-viewer.config.ts
import { PhaserViewerConfig } from 'phaser-viewer';

const config: PhaserViewerConfig = {
  filePath: './src/**/*.demo.ts',
  scene: {
    width: 1200,           // Custom canvas width
    height: 800,           // Custom canvas height  
    backgroundColor: '#1a1a2e'  // Custom background color
  }
};

export default config;

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | width | number | 800 | Canvas width in pixels | | height | number | 600 | Canvas height in pixels | | backgroundColor | string | '#222222' | Background color in hex format | | displayScale | number | auto | Display scaling factor (0.1-2.0, or omit for responsive auto-scaling) |

TypeScript Path Alias Support

Phaser Viewer automatically detects and resolves TypeScript path aliases from your tsconfig.json:

// tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"],
      "@/utils/*": ["./src/utils/*"]
    }
  }
}

// Your demo files can use path aliases
import { Button } from '@/components/Button';
import { COLORS } from '@/utils/colors';

Configuration Options:

// phaser-viewer.config.ts
export default {
  filePath: './src/**/*.demo.ts',
  // Auto-detection is enabled by default
  typescript: {
    autoDetectPaths: true,  // Default: true
    tsconfigPath: './tsconfig.json'  // Optional
  },
  // Or manually configure Vite aliases
  vite: {
    resolve: {
      alias: [
        { find: '@/', replacement: '/path/to/src/' }
      ]
    }
  }
}

🛠️ Commands

Development

  • npx phaser-viewer - Start development server with auto-detected configuration
  • npx phaser-viewer --port 3000 - Start on custom port
  • npx phaser-viewer --help - Show help

Testing

  • npx phaser-viewer test - Run automated tests for all Play functions

Test Runner Features:

  • Headless Testing: Runs components in headless browser environment
  • Play Function Tests: Each Play function becomes a test unit with pass/fail results
  • Error Details: Detailed error messages for failed tests
  • Clean Output: Filtered results without browser noise
  • Automatic Setup: Installs test dependencies automatically (vitest, playwright, @vitest/browser)

Configuration Detection:

  • Automatically loads phaser-viewer.config.ts or phaser-viewer.config.js
  • Generates default configuration file if none exists
  • Supports scene customization (size, background color)
  • Auto-adds .phaser-viewer-temp/ to .gitignore when present

📐 Development Grid System

Phaser Viewer includes a smart grid overlay system to help with precise component positioning during development:

Features

  • Square Grid Cells: Automatically calculates near-square grid cells for better visual alignment
  • Perfect Scene Coverage: Grid lines perfectly span your configured scene dimensions with no cutoff
  • Adaptive Sizing: Automatically adjusts to different screen sizes (100px, 120px, 80px target cells)
  • Always Visible: Grid appears in all demos for consistent development experience

How it Works

For a 1920×1080 scene:

  • Calculates 19×11 divisions (targeting ~100px square cells)
  • Creates cells of 101.1×98.2px (nearly perfect squares)
  • 18 vertical + 10 horizontal lines provide complete coverage
  • No manual configuration needed - works automatically

The grid system is enabled by default and helps developers align components precisely during development without any setup required.


📄 License

MIT License

🤝 Contributing

Contributions, issues and feature requests are welcome! Feel free to check issues page or contribute to the GitHub repository.