Storybook CLI: Develop, document, and test UI components in isolation
—
Run Storybook codemods to migrate source files between versions and configurations. The migration system uses JSCodeshift to transform your source code, updating deprecated patterns, API changes, and configuration formats automatically.
Execute codemods to transform source files for version migrations and configuration updates.
storybook migrate [migration] [options]
Parameters:
migration Name of the migration to run
Options:
-l, --list List available migrations
-g, --glob <glob> Glob for files upon which to apply the migration (default: "**/*.js")
-p, --parser <babel|babylon|flow|ts|tsx> jscodeshift parser
-c, --config-dir <dir-name> Directory where to load Storybook configurations from
-n, --dry-run Dry run: verify the migration exists and show the files to which it will be applied
-r, --rename <from-to> Rename suffix of matching files after codemod has been applied, e.g. ".js:.ts"Usage Examples:
# List all available migrations
npx storybook migrate --list
# Run specific migration
npx storybook migrate csf-2-to-3
# Dry run to preview changes
npx storybook migrate csf-2-to-3 --dry-run
# Migrate with custom file glob
npx storybook migrate update-imports --glob "src/**/*.stories.js"
# Migrate TypeScript files
npx storybook migrate api-update --parser tsx --glob "**/*.stories.tsx"
# Migrate and rename file extensions
npx storybook migrate js-to-ts --rename ".js:.ts"
# Migrate with custom config directory
npx storybook migrate addon-update --config-dir .custom-storybook
# Migrate specific file patterns
npx storybook migrate story-format --glob "src/components/**/*.stories.*"Common migrations provided by the Storybook ecosystem:
csf-1-to-2 - Migrate Component Story Format v1 to v2csf-2-to-3 - Migrate Component Story Format v2 to v3storiesof-to-csf - Convert storiesOf API to CSFmeta-3-to-2 - Downgrade CSF3 meta to CSF2 formatupdate-imports - Update import statements for new packagesaddon-info - Migrate addon-info to addon-docsaddon-notes - Migrate addon-notes to addon-docsaddon-knobs - Migrate addon-knobs to addon-controlsmain-config-v6 - Migrate main.js to v6 formatwebpack-config - Update webpack configurationtypescript-config - Migrate TypeScript configurationsreact-docgen - Update React docgen configurationvue-docgen - Update Vue docgen configurationangular-ivy - Migrate Angular Ivy configurationChoose the appropriate parser for your source files:
# JavaScript (default)
npx storybook migrate migration-name --parser babel
# TypeScript
npx storybook migrate migration-name --parser tsx
# Flow
npx storybook migrate migration-name --parser flow
# Babylon (alternative JavaScript parser)
npx storybook migrate migration-name --parser babylonControl which files are processed:
# Default: all JavaScript files
npx storybook migrate migration-name
# Custom glob pattern
npx storybook migrate migration-name --glob "src/**/*.stories.*"
# Multiple file types
npx storybook migrate migration-name --glob "**/*.{js,ts,jsx,tsx}"
# Specific directories
npx storybook migrate migration-name --glob "packages/*/src/**/*.stories.js"
# Exclude certain patterns
npx storybook migrate migration-name --glob "src/**/*.stories.js" --ignore "**/node_modules/**"Automatically rename files after migration:
# Rename .js to .ts
npx storybook migrate js-to-ts --rename ".js:.ts"
# Rename .jsx to .tsx
npx storybook migrate jsx-to-tsx --rename ".jsx:.tsx"
# Complex renaming pattern
npx storybook migrate story-update --rename ".stories.js:.stories.ts"Preview changes before applying them:
# See what files would be affected
npx storybook migrate csf-2-to-3 --dry-run
# Combine with custom glob for targeted preview
npx storybook migrate api-update --glob "src/**/*.stories.js" --dry-runMigrations are built using JSCodeshift transforms. Common patterns:
// Before migration
import { storiesOf } from '@storybook/react';
// After migration
import type { Meta, StoryObj } from '@storybook/react';// Before migration
storiesOf('Button', module)
.add('Primary', () => <Button primary />);
// After migration
export default {
title: 'Button',
component: Button,
} as Meta<typeof Button>;
export const Primary: StoryObj<typeof Button> = {
args: { primary: true },
};// Before migration
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-essentials'],
};
// After migration
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
],
framework: '@storybook/react',
};The migrate command delegates to the @storybook/codemod package:
import { listCodemods, runCodemod } from '@storybook/codemod';
/**
* List all available codemods
*/
function listCodemods(): string[];
/**
* Run a specific codemod
* @param codemodName - Name of the codemod to run
* @param options - Codemod execution options
*/
function runCodemod(codemodName: string, options: CodemodOptions): Promise<void>;
interface CodemodOptions {
glob: string;
dryRun?: boolean;
logger?: Logger;
rename?: string;
parser?: 'babel' | 'babylon' | 'flow' | 'ts' | 'tsx';
}import { migrate } from "@storybook/cli";
/**
* Run migrations programmatically
* @param migration - Name of the migration to run
* @param options - Migration configuration
*/
function migrate(migration: string, options: CLIOptions): Promise<void>;
interface CLIOptions {
glob: string;
configDir?: string;
dryRun?: boolean;
list?: string[];
rename?: string;
parser?: 'babel' | 'babylon' | 'flow' | 'ts' | 'tsx';
}Programmatic Examples:
import { migrate } from "@storybook/cli";
// Run migration programmatically
await migrate("csf-2-to-3", {
glob: "src/**/*.stories.js",
dryRun: false,
parser: "babel"
});
// List available migrations
await migrate(null, { list: true });Robust error handling for migration issues:
Install with Tessl CLI
npx tessl i tessl/npm-storybook--cli