Monday, August 24, 2026
HomeJavaScriptStorybook 3.0 for Aurelia 2: Goodbye Boilerplate

Storybook 3.0 for Aurelia 2: Goodbye Boilerplate


Bear in mind the setup directions from the Storybook publish again in February 2025? We informed you to place
this in .storybook/preview.ts:

export { render, renderToCanvas } from '@aurelia/storybook';

After which a viteFinal block to shove @aurelia/runtime-html into optimizeDeps.exclude, as a result of
in any other case Vite would pre-bundle it, you’d find yourself with two copies of the Aurelia runtime, and your
elements would break in ways in which made completely no sense. Good instances.

Delete all of it. @aurelia/storybook 3.0.0 simply landed on npm.

npm set up --save-dev @aurelia/storybook

Controls simply work now

That is simply probably the most thrilling elements of the discharge.

The outdated approach: write a render perform for each story, hand-write the template, then hand-write the
argTypes so that you’d get controls within the sidebar. Three locations to maintain in sync, for one part.
Miss one and also you’re sat there questioning why your slider does nothing.

The brand new approach:

import sort { Meta, StoryObj } from '@aurelia/storybook';
import { StatCard } from '../elements/stat-card';

const meta = {
  title: 'Elements/StatCard',
  part: StatCard,
  args: {
    label: 'Energetic customers',
    worth: 1284,
  },
} satisfies Meta<typeof StatCard>;

export default meta;

export const Default = {} satisfies StoryObj<typeof meta>;

That’s all it’s a must to do. No render perform, no template, no argTypes.

The framework reads your @bindable definitions and turns them into args, controls, and a bindables
desk within the docs. It solely binds the args you truly go, so any bindables you allow out preserve
their very own defaults as a substitute of getting stomped with undefined.

Twiddling a management now updates the working view mannequin in place as a substitute of nuking the app and
beginning over. Add or take away a bindable arg and yeah, it remounts, however altering a worth doesn’t. If
your part does actual work in its lifecycle hooks you’ll discover the distinction the primary time you
drag a slider.

Nonetheless need to write your personal templates? defineAureliaStory hasn’t gone anyplace. Use it for
projected content material, native assets, no matter markup you want. It’s simply not the default anymore.

The config received quite a bit shorter

.storybook/important.ts is typed now, and the builder wiring occurs for you:

import { defineMain } from '@aurelia/storybook/node';

export default defineMain({
  tales: ['../src/**/*.@(mdx|stories.@(ts|js))'],
  addons: ['@storybook/addon-docs', '@storybook/addon-a11y'],
  framework: {
    identify: '@aurelia/storybook',
    choices: {},
  },
  core: {
    builder: '@storybook/builder-vite',
  },
});

The preset provides the Aurelia Vite plugin in the event you haven’t already received one, and retains the Aurelia
runtime packages out of dependency pre-bundling so that you don’t find yourself with two copies. That complete
dance you used to do by hand is simply dealt with.

Swap that builder line for @storybook/builder-webpack5 or storybook-builder-rsbuild and also you get
the matching loader guidelines as a substitute. The February 2025 launch was Vite solely, with Webpack listed as
coming quickly. Webpack 5 and Rsbuild are correct first-class residents now.

Docs, factories and checks

Autodocs works. Add @storybook/addon-docs, tag your preview with autodocs, and also you get docs
pages the place the supply block exhibits the precise Aurelia markup your story rendered, not a serialised
object soup. MDX works with the traditional Storybook blocks, no particular Aurelia wrapper wanted.

When you’re into Storybook’s CSF Factories API, that’s wired up with actual Aurelia sort inference, so
preview.meta and meta.story learn about your part occasion, your decorators and your addon
parameters:

const meta = preview.meta({
  title: 'Instance/HelloWorld',
  part: HelloWorld,
  args: { message: 'Hiya from Storybook', onIncrement: fn() },
});

export const Default = meta.story({
  play: async ({ args, canvas }) => {
    await userEvent.click on(canvas.getByRole('button', { identify: 'Increment' }));
    await count on(args.onIncrement).toHaveBeenCalledWith(1);
  },
});

Play capabilities can seize mount in the event that they need to drive the preliminary render themselves. There are
transportable tales in @aurelia/storybook/portable-stories, so you possibly can yank a narrative straight right into a
Vitest take a look at with composeStories and name run() on it. And if you need the complete remedy,
Storybook’s Vitest addon will run your tales in actual Chromium.

Proper, what breaks

That is tagged a serious launch for a motive, some stuff has modified, so be sure to learn earlier than
upgrading.

Your preview file. If .storybook/preview.ts nonetheless has that export { render, renderToCanvas }
line, delete it. Storybook picks them up from the preset now, and exporting them your self simply
fights with it. framework, frameworkOptions, aureliaFramework and externals are gone too.
No person’s going to overlook them.

The host aspect. That is the sneaky one. Tales used to render inside
<sb-app containerless>, which meant no precise aspect within the DOM. Now they render inside
<sb-aurelia-story>,
which is an actual aspect that basically is there. So in the event you’ve received CSS or DOM snapshots that assume your
part sits immediately contained in the canvas, there’s a wrapper in the best way now. It received’t throw an
error. It’ll simply quietly look mistaken. Test your selectors.

Dependencies. @aurelia/runtime-html isn’t a peer dep anymore, and @aurelia/runtime is a
direct dependency as a substitute. Friends moved as much as Storybook 10.5.6 and Aurelia 2.0.0-rc.2. The
preview/varieties and preview/storybook-types subpaths are type-only now, so in the event you had been importing
them for a runtime worth that’ll break. Seize Storybook’s varieties from storybook/inner/varieties.

The total record is within the
changelog
.

Go break it

The
repo
has three instance apps in apps/, one per builder,
and CI retains all of them working. Best option to see an actual setup for no matter bundler you’re on.

When you bounced off Storybook final time as a result of the setup felt like a combat, give it one other go. And
if it nonetheless fights you, open a problem. We solely discover out about these items when somebody tells us.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments