Skip to content

Getting Started ​

A brief introduction setting up ember and storybook.

Requirements ​

PackageVersion
ember-source>=6.8.0
storybook^10.0.0

Your app should be an Ember app built with Vite.

NOTE

storybook init does not yet know about this framework. Setting up takes one install and two config files, so let's do it by hand — it's faster anyway.

Install ​

sh
pnpm add -D storybook ember-storybook
sh
npm install -D storybook ember-storybook
sh
yarn add -D storybook ember-storybook
sh
bun add -d storybook ember-storybook

Configuration ​

The config lives in .storybook/. main.ts configures the build, preview.ts configures what runs inside the preview iframe.

.storybook/main.ts
ts
import type { StorybookConfig } from 'ember-storybook';

const config: StorybookConfig = {
  stories: ['../app/**/*.stories.g(j|t)s'],

  framework: 'ember-storybook',
};

export default config;
.storybook/preview.ts
ts
import { createApp } from '../app/app';

import type { Preview } from 'ember-storybook';

const preview: Preview = {
  parameters: {
    ember: {
      app: createApp,
    },
  },
};

export default preview;

Ember specific configuration is set in parameters.ember.app. By default an empty App is booted for you, but you can set this for yourself.

  • an Application or ApplicationInstance class
  • a factory function returning one of those

All other Ember options (configure, owner, updateGlobals) are covered in App Context & Globals.

Add the Scripts ​

package.json
json
{
  "scripts": {
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  }
}

Write Your First Story ​

Colocate stories next to the component: button.stories.gts beside button.gts.

button.stories.gts
gts
import Button from './button.gts';

import type { Meta, StoryObj } from 'ember-storybook';

export default {
  title: 'Example/Button',
  component: Button
} satisfies Meta;

export const Primary: StoryObj = {
  args: {
    intent: 'action'
  }
};

That's it. The component is rendered with every arg passed down as a named argument — @intent — no render function needed. When you need full control over how the component is invoked (positional args, blocks, wrappers), give the meta an explicit render template:

button.stories.gts
gts
import Button from './button.gts';

import type { Meta } from 'ember-storybook';

export default {
  title: 'Example/Button',
  component: Button,
  render: (args) => <template>
    <Button @intent={{args.intent}}>
      {{args.label}}
    </Button>
  </template>
} satisfies Meta;

Run It ​

sh
pnpm storybook
sh
npm run storybook
sh
yarn storybook
sh
bun run storybook

Open http://localhost:6006 in your browser. Edit the story or the component and the canvas updates.

Where to Go Next ​

Released under the MIT License.