Storybook is an open-source tool for developing UI components for React, Svelte, Vue, Mithril, Web Components, and other similar systems. It's an evolution of design system frameworks and style kits like Pattern Lab, Zurb Foundation, or Bootstrap.

Over the years we've released various integrations with these tools for Drupal 7 through Drupal 9, providing popular theme implementations for Neato and Zurb Foundation, plus dozens of custom themes for projects based around Pattern Lab. These days, we find ourselves relying more on Storybook for new projects and less on older generation design systems.

The most common problem we've identified through implementation, README documentation, issue queues, and demos is that wrangling all the required resources to run tools like Storybook locally can be really tough. The mix of operating systems and configurations from computer to computer makes it difficult to provide a streamlined onboarding technique. Installation and development experiences vary from person to person.

That's where Docker comes in.

Run Storybook in Docker

We've been running Drupal in Docker since the start of 2018. Gone are the days of Virtualbox and Vagrant, for many of the same reasons we've already noted. The goal is consistent, predictable, and scalable onboarding for local development, and Docker can give that to us easily. 

Assuming you're already running a project in Docker (there are numerous community and commercially supported Docker stacks out there), you can create a container for Storybook in just a few lines of code in your docker-compose.yml file:

  node:
    image: wodby/node:15
    container_name: "myproject_node"
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html

  storybook:
    image: wodby/node:15
    container_name: "myproject_storybook"
    working_dir: /var/www/html
    command: npx start-storybook --static-dir ./build --port 8080
    labels:
      - traefik.http.services.${PROJECT_NAME}_storybook.loadbalancer.server.port=8080
      - traefik.http.routers.${PROJECT_NAME}_storybook.rule=Host(`storybook.myproject.docker.localhost`)
    volumes:
      - ./:/var/www/html

This provides you with two Node containers. One for executing Node tasks as a service, and the other for serving Storybook on your machine. We use Traefik to expose the Storybook container at the URL "storybook.myproject.docker.localhost".

The Storybook container is passed a command to run when the container is started. This executes the start-storybook command using the ./build folder in the container as the root, specifying port 8080.

With those two containers in place, anyone working on the project now has the ability to work on and view Storybook without having to install the correct version of NodeJS or NVM, deal with differences in Windows vs Mac vs Linux, or worry about any other host of issues. It also reduces the technical barrier of entry for project participants from hours to seconds. All that's required is checking out the code and starting your containers.

Now anyone on the team, developer and non-developer alike, can jump in at any point in the project and access the UI components in their browser:

A screenshot of what it looks like to edit Storybook components in Docker using a web browser

Running Node Tasks in Docker

Now that you don't need project members to install Node or related tools, you need a way to do execute NPM/Gulp/Node inside the Docker container. The good news is nothing changes about these commands. The only change is the system that executing them.

Let's say you want to run a Gulp task called "build". Under a project controlled by Docker, that command could look like this:

docker-compose run --rm node ./node_modules/.bin/gulp build (command arguments)

This is also tough for users unfamiliar with Docker. It can be a lot to remember, especially if you're running these tasks a lot. We solved this in our projects by also shipping them with an Ahoy! yaml file providing simple abstracted commands to get the same result:

  gulp:
    cmd: |
      echo "Running gulp $@"
      docker-compose run --rm node ./node_modules/.bin/gulp "$@"
    usage: Runs a Gulp task.

That long command above can now be done as:

ahoy gulp build (--args)

Developers and designers of any skillset can load, run, and build for Storybook without needing to know about installing software and package dependencies on their machine or getting hung up on any number of hurdles in that process.

This ensures the same consistent result across the board in local development - no more issues with build servers or team members having slightly different versions of Node or NPM packages.

Since this is also based on Docker, the commands can be used in a build/deploy continuous integration pipeline with the same images. An example GitLab CI job may look like the following:

build:
  image: wodby/node:15
  script:
    - npm ci
    - ./node_modules/.bin/gulp build --no-watch

Integrating to Drupal 9

Now you have one codebase powering two applicationsStorybook and Drupal 9 in Docker. Both are accessible in the browser, and all your tools are available via the provided Ahoy! command file. Developers and designers can work in one codebase without stepping on each other's toes and the flexibility of Docker can allow more skilled developers to create additional integrations without interfering with anyone else's workflow.

Integrating Storybook and Drupal 9 can be done using the Components module. The Components module provides a way for developers to register namespaces in their Twig templates to reference any defined path in the project—not just ones limited to a specific set of directories. Examples of this implementation can be seen with the Bootstrap Storybook theme project, bridging the two together. Amazee Labs has a great series of posts around GraphQL, Twig and Storybook for Drupal. The Emulsify design system for Drupal provides another great example of integrating Storybook with Drupal.

You can also just start with your own Storybook as we did above and work it into your project, based on your own needs. We have created several custom themes for clients and delivered the same tools in this article to their teams. We can provide assistance tailoring a Storybook design system and styleguide for your organization and integrating it with Drupal and other web properties. 

Reach out today to talk about how we can enable your teams on Drupal 9 and Storybook for your next project.