# Adding component stories This is what makes Markbook a Storybook alternative when you need one — the same engine that renders your docs can also mount live framework components into the page. > **See it live:** the [Pixie component demo](../demos/react-demo/) is this guide's payoff — a small component library rendered by Markbook, with stories, props tables, "show code" disclosures, and search. It's built from [`examples/react-demo`](https://github.com/doidor/markbook/tree/main/examples/react-demo) in the repo. ## Pick an adapter Markbook ships one adapter today: `@doidor/markbook-adapter-react` (mounts React components; `react` + `react-dom` as peer deps). Vue and Web Components adapters are on the [roadmap](https://github.com/doidor/markbook/blob/main/ROADMAP.md) — the core engine is framework-agnostic, so they're purely additive. Install it + its runtime: ```bash pnpm add -D @doidor/markbook-adapter-react pnpm add react react-dom ``` Then wire it into `markbook.config.ts`: ```ts import { defineConfig } from '@doidor/markbook-core'; import { reactAdapter } from '@doidor/markbook-adapter-react/config'; export default defineConfig({ title: 'My Components', adapter: reactAdapter(), }); ``` ## Write a story file A story file is a regular `.tsx` / `.ts` file that lives next to (or under) your markdown. **One story per file** is the convention: ```tsx // pages/Button/Primary.stories.tsx import { Button } from '../../../src/Button'; export default () => ; ``` That's it. No `Meta` object, no `decorator` wrapper required. The default export is the story. ## Reference it from markdown In any `.md` page: ```markdown ## Primary button :::story{src=./Button/Primary.stories.tsx} ::: ``` Build the site (`markbook build` or `markbook dev`). Markbook: 1. Inserts a placeholder `
` where the directive was. 2. Generates an entry script per page that imports each story module, then calls the adapter's `mount()` for each placeholder. 3. Renders a Shiki-highlighted source view under each mounted story (the "Show code" disclosure). The result: a live, fully-rendered React component inside your markdown, with its source visible for reference. ## Multi-export story files: `:::stories` When you have several variants of the same component, drop them all into one file as named exports: ```tsx // pages/Button/Button.stories.tsx import { Button } from '../../../src/Button'; export const Primary = () => ; export const Secondary = () => ; export const Disabled = () => ; ``` Then use `:::stories` (plural): ```markdown :::stories{src=./Button/Button.stories.tsx} ::: ``` Markbook discovers every named runtime export via TypeScript AST analysis, renders each as a card with its name (humanized — `Primary` → "Primary", `MyCoolStory` → "My cool story"), and slices the source disclosure per export. ## CSF v3 metadata (`args`, `argTypes`, `parameters`) If you've used Storybook before, the export shape is familiar: ```tsx export const Primary = { render: (args) => , args: { variant: 'primary', disabled: false }, argTypes: { variant: { control: 'select', options: ['primary', 'secondary'] }, disabled: { control: 'boolean' }, }, parameters: { layout: 'centered' }, }; ``` - **`args`** — initial prop values. With the React adapter, an interactive controls panel renders under the story so readers can tweak props live. - **`argTypes`** — control-type hints (`text`, `number`, `boolean`, `select`). Optional; inferred from `args` types when omitted. - **`parameters.layout`** — `centered` | `padded` | `fullscreen`. Controls how the story is positioned in its placeholder. Honored by the React adapter. ## Decorators (global providers) Wrap every story in shared providers (theme, i18n, router, ...): ```ts // markbook.config.ts import { reactAdapter } from '@doidor/markbook-adapter-react/config'; export default defineConfig({ adapter: reactAdapter({ decorators: ['./preview.tsx', './theme.tsx'], }), }); ``` ```tsx // preview.tsx — outer wrapper export default function Preview({ children }) { return
{children}
; } ``` Decorators apply outer-to-inner: `['A', 'B']` produces ``. ## Bundling stories for use outside the docs site `markbook bundle` packages each story as a portable artifact — `embed` mode produces a self-mounting ESM script you drop on any HTML page; `package` mode produces a publishable npm package directory with the framework as a peer dep. See the [`markbook bundle` CLI reference →](../reference/cli.html#markbook-bundle-storyid) for the full flag set and worked examples. ## Next steps - [Customization →](./customization.html) — restyle the chrome around your stories. - [Search & SEO →](./search-and-seo.html) — make sure your component docs are indexable. - [Config reference →](../reference/config.html) — full adapter + bundle options.