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

storybook-php

v0.3.0

Published

Storybook 10 framework addon for rendering PHP components as stories

Downloads

511

Readme

storybook-php

MIT License npm version

A Storybook framework addon for developing and previewing PHP components as stories.

Supported Versions

  • PHP 8.0-8.5
  • Storybook 10.x
  • Vite 5.x-8.x
  • Node.js 20.19+

Quick Start

.storybook/main.ts:

import type { StorybookConfig } from "storybook";

const config: StorybookConfig = {
  stories: ["../src/**/*.stories.ts"],
  framework: {
    name: "storybook-php",
    options: {},
  },
};

export default config;

src/Greeting.php:

<?php
class Greeting {
    public function __construct(private string $name, private string $greeting = 'Hello') {}

    public function render(): string {
        return "<h2>{$this->greeting}, {$this->name}!</h2>";
    }
}

src/Greeting.stories.ts:

import type { Meta, StoryObj } from "storybook-php";
import { Greeting } from "./Greeting.php@render";

const meta: Meta<typeof Greeting> = {
  component: Greeting,
  title: "Components/Greeting",
};

export default meta;
type Story = StoryObj<typeof Greeting>;

export const Default: Story = {
  args: { name: "World" },
};
npx storybook-php start

npx storybook-php

| Command | Description | | ----------------------------------------------------------- | ----------------------------------------------- | | npx storybook-php start [storybook opts] | Start the Storybook dev server | | npx storybook-php build [storybook opts] | Build static Storybook output | | npx storybook-php test [vitest opts] | Run Storybook tests through vitest run | | npx storybook-php typegen [dirs...] [--options-file path] | Generate declaration files for PHP import paths |

start and build accept the same options as the storybook CLI (e.g. -p 6006). test passes arguments through to vitest run.

typegen defaults to the src directory when no directories are specified. It writes declaration files next to the source import path, including exact-import outputs such as [email protected]. When defaultMethod resolves, the bare Button.php.d.ts output mirrors that callable; otherwise a bare import remains template-shaped.

If your type generation depends on defaultMethod or typeMap, pass them through --options-file because typegen does not read .storybook/main.ts. The options file can be JSON or a JS module and may also provide _configDir for relative path resolution.

For PHP-first repositories that do not want to add a local package.json, see PHP Project Setup for the npx-based setup.

Testing

npx --package=storybook-php --package=vitest \
    --package=@storybook/addon-vitest \
    --package=@vitest/browser-playwright \
    storybook-php test

Add @storybook/addon-vitest to .storybook/main.ts:

const config: StorybookConfig = {
  addons: ["@storybook/addon-vitest"],
  // ...
};

If your project does not define vitest.config.* and you do not pass --config, the bundled Vitest config is used automatically. To customize, create your own vitest.config.*.

Import Syntax

PHP components are imported with the ./File.php@method specifier. The @method suffix tells storybook-php which callable to invoke. Constructor parameters and method parameters are merged into the story's args.

| Pattern | Import Syntax | Args Source | | ---------------------------- | ----------------------------- | -------------------------------------- | | Class instance method | ./File.php@render | Constructor params + method params | | Static method | ./File.php@danger | Method params only | | Standalone function | ./file.php@funcName | Function params | | Invocable class | ./File.php@__invoke | Constructor params + __invoke params | | Enum method | ./File.php@swatch | _case + method params | | Template file | ./file.php (default import) | Template variables from args | | Mapped non-PHP import source | ./card.blade.php | typeMap.files decides the public API |

Methods that use echo instead of returning a string are captured via output buffering automatically.

Non-PHP sources such as Blade, Twig, or Latte are supported through framework.options.typeMap.files. Those mappings can provide public args, redirect execution to a PHP file, select a callable, include extra files for analysis, and attach adapter middleware.

Configuration

Configure in .storybook/main.ts under framework.options:

| Option | Type | Default | Description | | --------------- | ------------------------ | ----------- | -------------------------------------------------------------------------- | | bootstrap | string | undefined | Path to a PHP file executed before each render (autoloader, config, etc.) | | phpBinary | string | 'php' | Path to the PHP binary | | phpOptions | string[] | [] | CLI options prepended to PHP (e.g. ["-d", "memory_limit=512M"]) | | phpEnv | Record<string, string> | undefined | Environment variables merged over process.env when spawning PHP | | timeout | number | 5000 | Render timeout in milliseconds | | defaultMethod | string | undefined | Method name used when @method is omitted from the import specifier | | adapter | string | undefined | Path to a PHP adapter file for custom output handling (e.g. Laravel Blade) | | typeMap | object | undefined | File mappings, callable overrides, and runtime type bindings |

The adapter file must return middleware compatible with fn(array $context, callable $next): array|string

Relative option paths are resolved from Storybook's config directory. defaultMethod and typeMap also affect module resolution, TS plugin output, and typegen when you pass them through --options-file.

TypeScript Support

Add to tsconfig.json for type support on .php imports and IDE integration:

{
  "compilerOptions": {
    "types": ["storybook-php/client"],
    "plugins": [{ "name": "storybook-php/ts-plugin" }]
  }
}

This gives editor support for .php imports without requiring generated files.

To generate declaration files on disk:

npx storybook-php typegen

typegen writes both bare-import and exact-import declarations when they resolve:

For advanced setups, load defaultMethod and typeMap from a separate file:

npx storybook-php typegen --options-file storybook-php.config.mjs

Documentation

License

MIT