Storybook as Project Documentation
A few months ago I rediscovered Storybook.
For a long time I treated it mostly as a component playground. A place where you can open a button, switch props, check a few states, maybe show the result to another developer or designer.
That is still useful.
But today I see Storybook differently.
Storybook is not only a playground for components. It is also one of the best ways to keep project documentation close to the code and still read it as a real static website.
Not as a forgotten Markdown file hidden somewhere in GitLab.
Not as a README that is only opened when something breaks.
Not as a separate documentation system that slowly drifts away from the implementation.
Storybook can be the place where the package explains itself.
Documentation should live near the thing it explains
A component package usually needs several kinds of documentation:
- how to install it
- how to import it
- which props it accepts
- what each prop means
- which states are supported
- which states are not supported
- how it behaves with real content
- how it looks in edge cases
- how it should be tested
- when it should not be used
All of this can be written in Markdown or MDX near the component itself.
And then Storybook turns that documentation into a browsable static site.
That small shift matters.
A Markdown file in a repository is documentation for people who already know where to look.
A Storybook docs page is documentation that invites discovery.
It gives the project a visible map.
Stories make documentation honest
The best part is that Storybook documentation does not have to stop at text.
A docs page can explain the component and render the component on the same page.
That makes the documentation more honest.
If the text says that a ProfileCard supports a loading state, there can be a real Loading story next to that statement.
If the text says that a button has primary, secondary, disabled, and destructive states, those states can be visible immediately.
If the README says that the component works with long names, missing avatars, empty descriptions, and narrow containers, stories can prove it.
This is much better than documentation that only contains examples in code blocks.
Code examples describe intent.
Stories show behavior.
For UI packages, behavior is part of the API.
A package can document itself
This is why I started to think about Storybook as a core package surface.
For a calm component structure, a component folder can contain something like this:
profile-card/
component.tsx
component.test.tsx
types.ts
index.ts
index.test.ts
stories.tsx
doc.mdx
README.md
Each file has a clear job.
component.tsx contains the implementation.
types.ts contains the public contract.
component.test.tsx verifies behavior.
index.ts defines the package boundary.
README.md gives a simple package-level explanation.
doc.mdx gives a rich documentation page.
stories.tsx gives living examples.
The point is not to add files for the sake of ceremony.
The point is to make the component understandable without forcing someone to reverse-engineer the implementation.
A developer should be able to open the docs and understand how to use the component before reading the source code.
An AI assistant should also be able to read the README or docs page and understand the public contract without guessing from implementation details.
Storybook is a static documentation site
Another thing I started to appreciate more: Storybook can be built and published as static files.
That makes it very practical.
You can host it on S3 and CloudFront.
You can publish it from CI.
You can attach it to a package release.
You can keep it internal for a team or public for an open-source project.
You can use it as a design system site, a component catalog, a package manual, or a development workshop.
This fits calm architecture well.
The docs are static.
The examples are explicit.
The deployment is boring.
The project has a visible interface.
It works across many UI stacks
Storybook is also not only a React tool.
React support is great, but the bigger idea is more important: Storybook is a frontend workshop that can support many renderers and frameworks.
React, Vue, Angular, Web Components, Svelte, HTML-based components, and other integrations can all fit the same general model:
- write stories
- render isolated states
- document the public contract
- publish the result as a static site
That makes Storybook useful not just for one framework, but for a wider component culture.
Even when a stack is unusual, the idea still holds: isolate the component, document the contract, show real states, and make the result easy to browse.
Not every renderer has the same level of official support. Some integrations are first-class, some need custom setup, and some are community-driven. But the pattern is strong.
Storybook gives a project a place where UI behavior can be seen, not only described.
Modern Storybook is easier to own
Older Storybook setups often felt fragile.
They could depend too much on the application build setup. Webpack rules, Babel settings, aliases, CSS handling, framework plugins, and project-specific quirks could leak into the Storybook configuration.
That made Storybook powerful, but sometimes painful to maintain.
Newer Storybook versions feel more independent and more intentional.
The configuration is more focused around the Storybook project itself: where stories live, which framework integration is used, which builder is used, which addons are enabled, and how docs should behave.
That does not mean configuration disappeared.
It means Storybook has become easier to treat as its own project tool instead of a random side process attached to the application.
For me, this changed how I see it.
Storybook is no longer an optional toy that sits somewhere near the UI.
It is becoming one of the main project configs.
Like TypeScript.
Like ESLint.
Like Prettier.
Like Jest.
If a package has a public UI surface, Storybook deserves to be part of the baseline.
Storybook helps keep boundaries clear
A good story forces a component to be usable from the outside.
That is important.
If a component can only work when half of the application is running, it is probably not a calm component.
If it needs hidden global state, accidental context, random CSS side effects, or a backend call just to render a simple state, Storybook will reveal that quickly.
This is one of the underrated benefits.
Storybook is not only documentation.
It is architectural pressure.
It pushes components toward:
- clear inputs
- explicit props
- isolated rendering
- predictable states
- mockable dependencies
- stable public examples
That is exactly the kind of pressure a component system needs.
Stories are examples, tests, and documentation at the same time
A story starts as an example.
Then it becomes documentation.
Then it can become a visual test.
Then it can become an interaction test.
Then it becomes a contract for future maintainers.
This is why stories are valuable even when the component looks simple.
A simple story says:
This is a supported state.
That is already useful.
A group of stories says:
These are the states we care about.
That is even better.
For a design system or component package, stories are not just demos. They are part of the public API.
A practical documentation shape
For Vyriy-style packages, I like this split:
README.md
The README should stay simple.
It should explain:
- what the package does
- when to use it
- how to install it
- the smallest useful example
- links to deeper documentation
The README is the package entrance.
doc.mdx
The MDX documentation can go deeper.
It can include:
- motivation
- design principles
- API explanation
- examples
- usage notes
- limitations
- rendered stories
- links to related components
This is the page people read when they want to understand the component properly.
stories.tsx
Stories should focus on real states.
Not random playground noise.
Useful stories are things like:
- Default
- WithLongContent
- Loading
- Empty
- Error
- Disabled
- Compact
- Responsive
- WithCustomAction
Each story should represent a supported behavior.
If a story is not a meaningful state, it probably does not need to exist.
Storybook as part of calm architecture
Calm architecture is about systems that are understandable before they are clever.
Storybook fits that idea very well.
It makes UI packages visible.
It keeps documentation near the code.
It turns examples into a static site.
It encourages isolated components.
It makes supported states explicit.
It gives humans and tools a better way to understand the project.
And most importantly, it reduces guessing.
A component with stories and docs is easier to trust than a component that only exists as source code.
The shift in thinking
I used to think:
We can add Storybook if we need a playground.
Now I think:
We should add Storybook when the project has UI worth documenting.
That is a very different mindset.
A playground is optional.
Documentation is part of the product.
For a package, documentation is part of the API.
For a component, stories are part of the contract.
For a calm project, Storybook is not extra weight. It is a way to make the project easier to understand, maintain, test, and share.
That is why I now see Storybook as one of the core configs of a frontend project.
Not because every project needs a huge design system.
But because every serious UI package needs a clear, visible, living interface.