SolidJS is a fast, compact, and much-loved framework, especially among those who value performance and minimal abstractions.
It compiles to the lightest possible JavaScript, works directly with the DOM tree, and still has a JSX syntax like React, which makes it especially easy to compose components and understand for those who are used to working with React.
Essentially, you can write familiar code, but without all the burden that the React ecosystem carries.
However, when you start building a full-fledged application from dozens of components, the question quickly arises — how convenient is it to test and display these components in isolation from everything else? Waiting for the whole app to load, walking through the routers, disabling logic? Not exactly a fun dev loop.
And that's where Storybook comes in handy.
What is Storybook?
Storybook is a tool for isolated development of UI components. It allows you to run components outside the application, view them in different states, and document behavior and interaction with props. It's essentially a separate environment where each component — or even a separate part of the UI — is presented as an interactive “story,” with code, visuals, and settings.
You plug in your components, describe how they should be displayed, and get a convenient environment for debugging, demonstrating, and collaborating on the UI.
You can check a real-time example of Storybook with SolidJS in this Stackblitz demo
SolidJS support in Storybook
This is the part where the complications start. Unfortunately, the Storybook team doesn't have enough resources to support all existing — or even just popular — frameworks, so they are mostly focused on the React version.
The storybook-solidjs
community adapter is not really supported by the community, has broken dependencies, a number of bugs, no testing support, no automatic generation of documentation from TypeScript typings, and it doesn't work with Storybook 9. You'll be lucky if you can get it to work at all.
Half a year ago, I got it to work by some miracle. But a month ago, something updated, and it stopped running again.
So I decided to take things into my own hands and developed my own adapter for Storybook in SolidJS, as well as a CLI for easy customization.
The current package is published as @kachurun/storybook-solid-vite, but we’re working on moving it under storybook-solidjs, which is the one referenced in the official Storybook docs.
The code is published in the solidjs-community/storybook GitHub repository.
Huge thanks to the folks behind storybook-solidjs. This project wouldn’t exist without the foundation they laid.
Features
- Hot Reload – Instant updates as you edit components, powered by Vite
- Integrated Testing – Built-in support for component and story testing with Vitest and Playwright
- ArgTypes from TypeScript – Prop tables and controls generated directly from your TypeScript types
- Addon Ecosystem – Works with popular Storybook addons (Docs, Controls, Actions, Links, etc.)
- MDX & Docs – Write rich documentation alongside your stories using MDX
- Accessibility (a11y) – Built-in accessibility checks for your components
Setup
For ease of deployment from scratch, I have created a package, create-solid-storybook, that will automatically create all the necessary files and some sample stories.
Execute:
npx create-solid-storybook
If you prefer a different package management system:
Yarn
yarn create-solid-storybook
PNPM
pnpm create solid-storybook
Bun
bunx create-solid-storybook
Important: Storybook 9 requires Node.js version 20 or higher to run.
The utility will automatically deploy the necessary files and sample stories to the storybook
folder (you can specify the folder name as the second argument when running the command), install dependencies, and start Storybook.
The browser with the running Storybook will open automatically at http://localhost:6006/.
Project structure:
storybook/
├── .storybook/
│ ├── main.ts # Main configuration file
│ └── preview.ts # Global parameters and decorators
│
├── stories/ # Sample components and stories for them
│
├── tsconfig.json # TypeScript configuration
├── vitest.config.ts # Vitest configuration
└── package.json # Project dependencies and scripts
The main.ts
file is where Storybook itself, its plugins, Vite settings, etc., are configured.
The main line for working with SolidJS is the framework setting, which tells Storybook how to work with our component files:
framework: '@kachurun/storybook-solid-vite',
You can change any configuration settings other than this line.
The preview.ts
file is connected inside the iframe in which your story is rendered. If you want, for example, to connect some global CSS, you must import it in this file. The file is also responsible for default configuration for all stories.
The stories
folder contains sample components and stories for them. Most likely, you will just delete it, but it is needed as an example.
I prefer to keep all stories in this folder and the components themselves outside the Storybook directory, in the source code of the project itself.
Many people prefer to store stories next to their components. In that case, you will need to open the main.ts
file and specify the path to your stories files, for example:
stories: [
'../../src/**/*.mdx',
'../../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
],
Stories format
The stories format for SolidJS is not different from the React format.
You create a file [componentName].stories.tsx
with content like this:
import { fn } from 'storybook/test';
import { Button } from './Button';
export default {
title: 'Example/Button',
component: Button,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
backgroundColor: { control: 'color' },
},
args: { onClick: fn() },
};
export const Primary = {
args: {
primary: true,
label: 'Button',
},
};
Note: each story must export at least one named export.
You can use CSF format:
export const ButtonCSF = (args: ButtonProps) => {
return <Button size="small" label="Button" {...args} />;
};
Or use decorators to frame the component:
export const WithDecorator = {
args: {
size: 'small',
label: 'Button',
primary: true,
},
decorators: [
(Story: Component<ButtonProps>, context: { args: ButtonProps }) => {
return (
<div class="border border-dashed border-red-500 p-2">
<Story {...context.args} />
</div>
);
},
],
};
Everything is exactly the same as with React components, so you can use the standard Storybook documentation.
Customizing Tailwind CSS 4
Since our Storybook configuration uses Vite for the build, setting up Tailwind will be very easy.
In the running terminal, press Cmd + C
to end the Storybook process, navigate to the storybook
folder, and install Tailwind:
cd storybook
npm install tailwindcss @tailwindcss/vite
You can skip this step if your project already uses Tailwind.
Then open the .storybook/main.ts
file and add the Tailwind plugin in the viteFinal
config:
export default <StorybookConfig>{
...
async viteFinal(config) {
return mergeConfig(config, {
define: {
'process.env': {},
},
plugins: [
await import('@tailwindcss/vite').then(module => module.default())
],
});
},
...
}
We use dynamic importing to solve a strange bug in Tailwind CSS that is marked as solved but still occurs.
Next, create a CSS file (the name can be anything) with the contents:
@import "tailwindcss";
If your working project already has a file with this import, skip this step.
I will create this file at the path .storybook/preview.css
.
Next, import this file in .storybook/preview.ts
:
import './preview.css';
...
Done! You can now run Storybook:
npm run storybook
To test it, let's edit some component — for example, stories/Button.tsx
— and add Tailwind classes to it:
export const Button = (_props: ButtonProps) => {
const [props, attrs] = splitProps(
mergeProps({ size: 'medium' }, _props),
['label']
);
return (
<button
type="button"
class="px-4 py-3 text-sm bg-blue-500 text-white rounded-full"
{...attrs}
>
{props.label}
</button>
);
};
Next, open the story and make sure the styles are applied.
That's enough to start developing, debugging, and testing your SolidJS components!
Feel free to comment if you have any questions, and feel free to open an issue if you have any problems with your configuration!
Hey everyone! We’re launching your special Dev.to drop for all verified Dev.to authors. Don’t miss this opportunity here to see if you qualify (no gas fees). – Dev.to Team