How it works
This page walks through the moving parts of the integration, from the CLI command down to the webpack loaders. Package entry points of @archibald/storybook:
| Entry point | Contents |
|---|---|
@archibald/storybook | StorybookProvider (runtime, used in preview.tsx) |
@archibald/storybook/config | defineConfig() (used in main.ts) |
@archibald/storybook/preset | the Storybook preset that injects the Archibald build config |
@archibald/storybook/loader | the babel shadowing loader plugin (registered by the preset) |
The CLI command
archibald storybook (reference) does not reimplement Storybook — it prepares the environment and delegates to the Storybook CLI:
- Dependency check — verifies
@archibald/storybookis installed and aborts with a hint otherwise. - Prompting — asks for environment, tenant, platform, and compile mode (plus the Vercel question when
cli/storybook/vercel/activeistrue), unless the values were passed as flags. - Environment setup — sets
APP_CODE=clientand serializes the selected parameters and the full resolved Archibald config into theSTORYBOOK_PARAMSandSTORYBOOK_CONFIGenvironment variables. This is how the preset and the story loader — which run inside Storybook's own process — learn about the selected tenant/platform and yourarchibald.json. - Launch — spawns
npx storybookwithdev -c <cli/storybook/config> -p <cli/storybook/port>indevelopmentmode, orbuild -c <cli/storybook/config> --output-dir <dist>/<storybook output path>inproductionmode, forwarding--no-open,--quiet, and the configured log level.
- Vercel transform (optional) — after a production build with
--vercel, converts the static output into a Vercel Build Output under.vercel/output(see Deploying Storybook to Vercel).
defineConfig()
defineConfig() from @archibald/storybook/config produces the Storybook main config by deep-merging your overrides onto this base:
{
stories: loadStories, // the shadowing-aware story loader
addons: [
'@storybook/addon-docs',
'@storybook/addon-onboarding',
'@storybook/addon-a11y',
'@chromatic-com/storybook',
'@archibald/storybook/preset'
],
framework: { name: '@storybook/react-webpack5', options: {} },
docs: { defaultName: 'Documentation' },
typescript: { reactDocgen: 'react-docgen-typescript' }
}
Merge rules:
- Arrays (e.g.
addons) are concatenated, with your entries first. defineConfig(config, { override: true })makes your arrays replace the base arrays instead.- Passing your own
storiesvalue replaces the automatic loader entirely.
Note that the Archibald preset is registered as one of the addons — that is how it hooks into Storybook's build.
The preset
@archibald/storybook/preset is a standard Storybook preset. It reads STORYBOOK_CONFIG/STORYBOOK_PARAMS, resolves the tenant and platform chains, and exports:
addons— registers@storybook/addon-webpack5-compiler-swc, so Storybook compiles with swc.swc(config)— swc options matching the app build: TypeScript + TSX parsing, decorators, and the automatic or classic JSX runtime depending oncli/development/automaticRuntime.webpackFinal(config)— the core piece. It mutates Storybook's webpack config to match the Archibald client build:- Removes Storybook's built-in CSS rule and points
resolve.modulesat the project'ssrcfolder, so base-path imports (shop/client/...) resolve. - Adds the TypeScript rule:
babel-loaderrunning the@archibald/storybook/loaderbabel plugin (the same shadowing loader as the app build, configured with the selected tenant/platform chains), optionally@babel/preset-env+ core-js (whencli/optimization/coreJSis enabled and a.browserslistrcexists) and react/prefresh fast-refresh in dev — followed byswc-loader. - Adds the style rules described below.
- Adds the SVGR rule when
cli/optimization/svgComponentsis enabled. - Defines the same compile-time constants as the app bundle via
DefinePlugin— notablyprocess.env.APP_CODE = "client"andprocess.env.ARC_SINGLE_ROOT_ISLANDS, so a story rendering a hydration island exercises the samewithHydrationimplementation the project ships. - Aliases each platform name to its
src/<platform>folder, aliasesreact-nativetoreact-native-webwhen installed, and stubs Node built-ins (child_process,os,module) for the browser.
- Removes Storybook's built-in CSS rule and points
The story loader
defineConfig() sets stories to a loader function instead of a glob list. On (re)build it:
- reads the selected tenant/platform from
STORYBOOK_PARAMS, - recursively lists
src/<selected platform>and, if different,src/<default platform>, - keeps files matching
**/*.mdxand**/*.stories.@(js|jsx|mjs|ts|tsx), - runs entries from the default-platform fallback through the shadowing resolver and drops any file that resolves to a more specific override for the selected tenant/platform chain.
The behavior from a story author's perspective is described in Writing stories.
The style pipeline
Styles use the same loader chain as the application's client build, with one difference: since Storybook serves everything from one dev bundle, styles are injected with style-loader instead of being extracted to CSS files. The chain is:
style-loadercss-loader— CSS modules on or off (and hashed class names in production) according tocli/style/modulesresolve-url-loadersass-loader—sass-embeddedwith the modern API,includePathscoveringsrcandnode_modules, and thescssShadowingImporterconfigured with the selected tenant/platform chains, so@use/@importstatements resolve tenant and platform style overrides exactly like the app build.
StorybookProvider
The runtime export (@archibald/storybook) is a thin wrapper for use in preview.tsx decorators or individual stories:
- renders
TestingProvidersfrom@archibald/testing/providerswith a context created viacreateContext— providing the app client, data client, and translation contexts, - wraps children in a
MemoryRouter, - adds the
themeclass todocument.bodywhile mounted (removed on unmount).
Configuration reference
The cli/storybook block in archibald.json:
| Key | Type | Default | Description |
|---|---|---|---|
open | boolean | true | Open the browser after the dev build. |
config | string | .storybook | Path to the Storybook config folder. |
port | number | 3400 | Port of the Storybook dev server. |
vercel.active | boolean | false | Offer the --vercel flag on production builds. |
vercel.config | object | — | Optional vercel.json overrides for the generated Vercel Build Output. |
The static production build lands in project/output/paths/dist + project/output/paths/storybook (defaults: dist + stories → dist/stories).