0
# Preset System
1
2
Powerful preset loading and application system for managing Storybook addons and framework configurations. The preset system allows for modular, composable configuration that can be shared across projects.
3
4
## Capabilities
5
6
### Core Preset Functions
7
8
Create and manage preset application interfaces for dynamic configuration management.
9
10
```typescript { .api }
11
/**
12
* Create preset application interface from preset configurations
13
* @param presets - Array of preset configurations
14
* @param storybookOptions - Storybook options for preset context
15
* @returns Promise resolving to Presets interface
16
*/
17
function getPresets(
18
presets: PresetConfig[],
19
storybookOptions: InterPresetOptions
20
): Promise<Presets>;
21
22
/**
23
* Load and merge all preset configurations including core, custom, and override presets
24
* @param options - Preset loading options
25
* @returns Promise resolving to merged Presets interface
26
*/
27
function loadAllPresets(options: {
28
corePresets?: PresetConfig[];
29
overridePresets?: PresetConfig[];
30
configDir: string;
31
isCritical?: boolean;
32
build?: TestBuildConfig;
33
}): Promise<Presets>;
34
35
interface Presets {
36
/**
37
* Apply preset extension to configuration
38
* @param extension - Extension name (e.g., 'babel', 'webpack', 'stories')
39
* @param config - Current configuration to extend
40
* @param args - Additional arguments for preset functions
41
* @returns Promise resolving to extended configuration
42
*/
43
apply<T>(extension: string, config?: T, args?: unknown): Promise<T>;
44
}
45
```
46
47
**Usage Example:**
48
49
```typescript
50
import { loadAllPresets } from "@storybook/core-common";
51
52
// Load all presets for a Storybook project
53
const presets = await loadAllPresets({
54
configDir: '.storybook',
55
corePresets: ['@storybook/core-server/presets/common-preset'],
56
overridePresets: []
57
});
58
59
// Apply babel preset
60
const babelConfig = await presets.apply('babel', {}, { configType: 'DEVELOPMENT' });
61
62
// Apply stories preset
63
const stories = await presets.apply('stories', [], {});
64
```
65
66
### Individual Preset Loading
67
68
Load and process individual preset configurations.
69
70
```typescript { .api }
71
/**
72
* Load individual preset configuration
73
* @param input - Preset configuration (string or object)
74
* @param level - Nesting level for recursive loading
75
* @param storybookOptions - Storybook context options
76
* @returns Promise resolving to array of loaded presets
77
*/
78
function loadPreset(
79
input: PresetConfig,
80
level: number,
81
storybookOptions: InterPresetOptions
82
): Promise<LoadedPreset[]>;
83
84
interface LoadedPreset {
85
name: string;
86
preset: any;
87
options: any;
88
}
89
```
90
91
### Addon Resolution
92
93
Resolve addon names to preset or virtual addon configurations.
94
95
```typescript { .api }
96
/**
97
* Resolve addon name to preset or virtual addon configuration
98
* @param configDir - Configuration directory for resolution context
99
* @param name - Addon name or path
100
* @param options - Addon-specific options
101
* @returns Resolved addon configuration or undefined if not found
102
*/
103
function resolveAddonName(
104
configDir: string,
105
name: string,
106
options: any
107
): CoreCommon_ResolvedAddonPreset | CoreCommon_ResolvedAddonVirtual | undefined;
108
109
interface CoreCommon_ResolvedAddonPreset {
110
type: 'presets';
111
name: string;
112
}
113
114
interface CoreCommon_ResolvedAddonVirtual {
115
type: 'virtual';
116
name: string;
117
managerEntries?: string[];
118
previewAnnotations?: PreviewAnnotation[];
119
presets?: (string | { name: string; options?: any })[];
120
}
121
```
122
123
**Usage Example:**
124
125
```typescript
126
import { resolveAddonName } from "@storybook/core-common";
127
128
// Resolve addon with manager entry
129
const essentialsAddon = resolveAddonName(
130
'.storybook',
131
'@storybook/addon-essentials',
132
{}
133
);
134
135
// Resolve addon with custom manager
136
const customAddon = resolveAddonName(
137
'.storybook',
138
'@storybook/addon-docs/manager',
139
{ theme: 'dark' }
140
);
141
142
console.log(essentialsAddon);
143
// { type: 'presets', name: '/path/to/@storybook/addon-essentials/preset' }
144
```
145
146
### Preset Filtering
147
148
Filter and process preset configurations.
149
150
```typescript { .api }
151
/**
152
* Filter preset configurations, removing deprecated presets
153
* @param presetsConfig - Array of preset configurations
154
* @returns Filtered preset configurations
155
*/
156
function filterPresetsConfig(presetsConfig: PresetConfig[]): PresetConfig[];
157
```
158
159
### Custom Preset Loading
160
161
Load custom presets from main configuration.
162
163
```typescript { .api }
164
/**
165
* Load custom presets from main configuration
166
* @param options - Options containing main config and preset context
167
* @returns Array of custom preset configurations
168
*/
169
function loadCustomPresets(options: {
170
configDir: string;
171
presets?: Presets;
172
}): PresetConfig[];
173
```
174
175
## Preset Configuration Types
176
177
```typescript { .api }
178
/**
179
* Preset configuration - can be string path or object with options
180
*/
181
type PresetConfig = string | {
182
name: string;
183
options?: unknown;
184
};
185
186
/**
187
* Preset definition - string path or object with name and options
188
*/
189
type Preset = string | {
190
name: string;
191
options?: any;
192
};
193
194
/**
195
* Preview annotation configuration for virtual addons
196
*/
197
type PreviewAnnotation = string | {
198
bare: string;
199
absolute: string;
200
};
201
```
202
203
## Advanced Usage
204
205
### Creating Custom Presets
206
207
```typescript
208
// Custom preset file structure
209
module.exports = {
210
// Extend babel configuration
211
babel: (config, { configType }) => ({
212
...config,
213
plugins: [
214
...config.plugins,
215
configType === 'DEVELOPMENT' && 'babel-plugin-dev-tools'
216
].filter(Boolean)
217
}),
218
219
// Add webpack configuration
220
webpackFinal: (config, { configType }) => {
221
if (configType === 'DEVELOPMENT') {
222
config.devtool = 'eval-source-map';
223
}
224
return config;
225
},
226
227
// Define stories
228
stories: (entries = []) => [
229
...entries,
230
'../src/**/*.stories.@(js|jsx|ts|tsx)'
231
],
232
233
// Add addons
234
addons: [
235
'@storybook/addon-essentials',
236
{
237
name: '@storybook/addon-docs',
238
options: { transcludeMarkdown: true }
239
}
240
]
241
};
242
```
243
244
### Functional Presets
245
246
```typescript
247
// Functional preset that receives options
248
module.exports = (options = {}) => ({
249
babel: (config) => ({
250
...config,
251
plugins: [
252
...config.plugins,
253
options.enableExperimentalFeatures && 'babel-plugin-experimental'
254
].filter(Boolean)
255
}),
256
257
addons: [
258
'@storybook/addon-essentials',
259
...(options.enableDocs ? ['@storybook/addon-docs'] : [])
260
]
261
});
262
```
263
264
## Supporting Types
265
266
```typescript { .api }
267
interface InterPresetOptions {
268
configDir: string;
269
packageJson?: PackageJson;
270
outputDir?: string;
271
cacheKey?: string;
272
ignorePreview?: boolean;
273
isCritical?: boolean;
274
build?: TestBuildConfig;
275
}
276
277
interface TestBuildConfig {
278
test?: {
279
disabledAddons?: string[];
280
disableBlocks?: boolean;
281
disableMDXEntries?: boolean;
282
disableAutoDocs?: boolean;
283
disableDocgen?: boolean;
284
disableSourcemaps?: boolean;
285
disableTreeShaking?: boolean;
286
esbuildMinify?: boolean;
287
};
288
}
289
```