SolidJS integration with Storybook

View on GithubNew to Storybook?Get started

Storybook for SolidJS

Storybook SolidJS Vite

npm version npm downloads MIT License PRs Welcome

Storybook framework adapter for SolidJS on Vite.

✨ Features

🚀 Getting Started

Run in your project:

npx create-storybook --type=solid
npm run storybook

Open the URL shown in the terminal.

⚙️ Configuration

Customize Vite and Storybook as usual. Add stories in src/**/*.stories.{tsx,js} and install addons as needed.

CSF Next

// .storybook/main.ts
import { defineMain } from 'storybook-solidjs-vite';

export default defineMain({
  framework: { name: 'storybook-solidjs-vite' },
});
// .storybook/preview.tsx
import addonDocs from '@storybook/addon-docs';
import { definePreview } from 'storybook-solidjs-vite';

export default definePreview({
  addons: [addonDocs()],
});
// src/Button.stories.ts
import preview from '../.storybook/preview';
import { Button } from './Button';

const meta = preview.meta({
  component: Button,
});

export const Primary = meta.story({
  args: { label: 'Button' },
});

CSF 3

// .storybook/main.ts
import type { StorybookConfig } from 'storybook-solidjs-vite';

export default {
  framework: 'storybook-solidjs-vite',
} satisfies StorybookConfig;
// src/Button.stories.ts
import type { Meta, StoryObj } from 'storybook-solidjs-vite';

import { Button } from './Button';

const meta = {
  component: Button,
} satisfies Meta<typeof Button>;

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

export const Primary: Story = {
  args: { label: 'Button' },
};

Docgen

Props for Controls, Docs, and the components manifest come from a TypeScript LanguageService extractor aligned with Storybook's react-component-meta format.

Enabled by default. Inspect output in the manifest debugger.

To disable:

import type { StorybookConfig } from 'storybook-solidjs-vite';

const config: StorybookConfig = {
  framework: {
    name: 'storybook-solidjs-vite',
    options: { docgen: false },
  },
};

export default config;

Autodocs code snippets

Show code blocks are static snippets generated from story source at index time (experimentalCodeExamples). Enabled by default.

To disable:

import type { StorybookConfig } from 'storybook-solidjs-vite';

const config: StorybookConfig = {
  features: {
    experimentalCodeExamples: false
  },
};

export default config;

Storybook MCP

Solid projects can use Storybook MCP so AI agents can list components, read prop docs from component meta, and preview stories. Requires docgen (enabled by default) and @storybook/addon-docs.

npx storybook add @storybook/addon-mcp

See Storybook MCP docs for agent setup.

Components manifest debugger

Storybook builds JSON manifests from CSF stories and component source — names, props, JSDoc, story ids, and more. Enabled by default (features.componentsManifest). Prop data comes from docgen; story snippets use the same code generator.

While Storybook runs (or in a static build):

  • Debugger UI: http://localhost:6006/manifests/components.html — browse manifests and generation errors/warnings
  • Components JSON: http://localhost:6006/manifests/components.json
  • Docs JSON: http://localhost:6006/manifests/docs.json (when MDX docs are present)

🎨 Decorators

On args or globals changes, Storybook re-runs decorators and stories functions follows React reactivity model. Solid updates via fine-grained signals and usually doesn't need that. JSX decorators re-run can leave duplicate DOM nodes. To avoid this, use createJSXDecorator function to define decorators that return JSX.

createJSXDecorator

For decorators that return JSX. Runs once per story mount — context.globals and context.args are reactive stores, so bindings in JSX still update without re-running the decorator:

import { createJSXDecorator } from 'storybook-solidjs-vite';

export const withLayout = createJSXDecorator((Story, context) => (
  <main data-theme={context.globals.theme}>
    <Story />
  </main>
));

createDecorator

For side effects that should run on every story update — e.g. sync document.body when globals change:

import { createDecorator } from 'storybook-solidjs-vite';

export const withTheme = createDecorator((Story, context) => {
  // Will run on every story update
  document.body.setAttribute('data-theme', context.globals.theme);
  return Story();
});

🔄 Migration from v9

See Migration Guide for breaking changes.

🤝 Contributing

Issues and PRs welcome — open an issue or submit a pull request.

📖 License

MIT

👤 Maintainer

Maintained with ❤️ by @kachurun