Build a Stencil and Storybook Environment

mabryCodes
5 min readMar 7, 2021
Goes together like peanut butter and jelly.

I have been using Stencil.js and Storybook to build components for design systems and I have really been enjoying the workflow, one might even say they go together like peanut butter and jelly.

The tooling I have been using at work uses these two technologies with all the bells and whistles needed for interacting with various other tools. I’m pretty obsessed with it at the moment and decided that I wanted to build a stripped down version of this system to learn and teach these amazing technologies in isolation. I also wanted to share this process as a way to better understand it myself and to teach anyone who is curious how they can do it too.

If you want to just see or use the starter file, you can find it on my Github.

Getting Started

Create your Stencil.js application in your working directory:

npm init stencil

We will be picking component as a starter:

? Pick a starter › — Use arrow-keys. Return to submit.
ionic-pwa Everything you need to build fast, production ready PWAs
app Minimal starter for building a Stencil app or website
> component Collection of web components that can be used anywhere

Enter your project name and confirm:

✔ Pick a starter › component
? Project name › your-app

Now lets change directories to our newly created Stencil app and install the dependencies:

cd your-appnpm install

Let’s go ahead and fire up Stencil and make sure that we got everything running fine so far:

npm start

If all goes well you should be directed to localhost:3333 in your browser and you should see the following demo web component:

Great, looking good so far! Let’s go ahead and terminate that process using ctrl + C .

Storybook

Let’s add Storybook to our project. We will initialize storybook and configure it as an HTML project.

(Note: There is a method to setup the project explicitly for web components, but as of writing this, the add-on is in beta and requires additional setup. If you are interested in trying to set it up in this way, the web component add-on can be found here)

In the root directory run:

npx sb init? Do you want to manually choose a Storybook project type to install? Yes? Please choose a project type from the following list: HTML

We’ll need to open up .storybook/preview.js and add the following to let Storybook know to load our web components:

If this is empty then jsfiddle is down currently :(

Let’s do a little refactoring to the file structure. This step is not necessary, it is just how I like to organize my stories.

First we move the src/stories folder to the .storybook folder, this is where we will store our general stories, like introduction.stories.mdx and also to keep the example stories for reference.

Be sure you are still in the root directory of the project and run:

mv src/stories .storybook

Now we need to open .storybook/main.js and add the following lines to module.exports so Storybook knows where to find these stories that we just moved:

If this is empty then jsfiddle is down currently :(

We will keep stories for web components we build in the component directories themselves.

Let’s add a story file to the my-component component that Stencil built for us.

(This file will be blank initially and therefore we will not see it in storybook yet. Adding this here to suppress an error and we will build out the story later)

In the root directory of the project, run:

touch src/components/my-component/my-component.stories.ts

Now lets fire up Storybook and make sure that it is setup and running:

npm run storybook

With everything going as planned, you will be taken to localhost: 6006 and should see the following page:

(Note that we have our introduction and sample stories in the sidebar)

Now that we know that is setup, let’s terminate that process using ctrl + C.

Flip the Script

Next we need to add a “build.watch” script to our package.json so that we can run a watcher for Stencil to detect any changes we make in our component:

If this is empty then jsfiddle is down currently :(

We’ll need to add concurrently as a dev dependency, this will allow us to setup a script that can run multiple scripts in parallel:

npm install concurrently --save-dev

Next we will add another script to package.json that will run both the “build.watch” and “storybook” scripts in parallel.

Insert the new “dev” script:

If this is empty then jsfiddle is down currently :(

Now run:

npm run dev

You should see the same Storybook content as before at localhost: 6006. The difference is now we have Stencil also watching for changes to the component to trigger hot reloading of the component in Storybook.

Story Time

Okay, now we’ve got the environment up and running, let’s go ahead and build a story for my-component to test everything out.

Without getting too deep into how to build stories, what we are doing here is:

  • defining where we want our story displayed in the sidebar in title
  • defining which component we are pointing to in component
  • defining which argument types we want to pass in with argTypes along with control type and defaultValue
  • creating the arrow function MyComponent where we destructure our arguments and render the component in the return using a template literal.
  • passing in our arguments as props to my-component
If this is empty then jsfiddle is down currently :(

Now we should see Example > Demo > My Component in the sidebar of our Storybook:

(If Storybook didn’t detect our new story, try to refresh your browser. If that doesn’t work then terminate the process and run npm run dev again)

All done!

So there we go, now you have your very own starter to build web components using Stencil and you can view and test those components live using Storybook.

I’ll be using this starter to put together tutorials for Stencil and Storybook and I’ll be experimenting with different tools and sharing my processes.

In the meantime if you want to jump in and learn more yourself go checkout the respective docs here and here to get started. See you next time!

--

--

mabryCodes

A frontend developer with a passion for web components and design systems