Practicing Tech Design with React, Storybook, and Nivo

Jon Walz · May 23, 2019

Design · Learning · Evaluating

I spent the weekend making a technical design and implementing it to challenge myself and evaluate a few different unfamiliar libraries. I've read a lot of positive reviews of Storybook, so I figured creating a small project would be a good way to evaluate. Driven by my interest in Nivo, a charting library, I thought an easy bit of data to visualize would be my TreeHouse profile points.

The React Suspense API and react-fetching-library were technologies that have piqued my interest lately, so I included these intentionally. I’m rather happy with the result other than having to create my own node server to get around a Treehouse server issue (or rather an issue with the client library. More on that later).

I first created a technical design to plan out the broad, architectural pieces needed for the app. The process involved researching what would be needed from the newer and unfamiliar technologies and formulating a procedure for implementing them.

Then, I executed my plan and took note of my opinions regarding the unfamiliar technologies and the hiccups along the way.

The result

Self-Chart Technical Design

High Level Design

Chosen Technologies

High level Todo items

  • Bootstrap a development cycle by creating a storybook version of components needed in this project.
  • Create UI layer with React.
  • Define tests, components, client, and data transformation.
  • Create client for fetching needed data.
  • Create data transformation utility for UI consumption.

No state management library is needed for this simple example. Though no other library is really needed either for something this simple. I just want to learn about them.

Low Level Design


  1. Use create-react-app with typescript to get up and running.
  2. Start a git repo.
  3. Deploy on codesandbox to show the world.



  yarn add
  yarn add -D typescript
  yarn add -D awesome-typescript-loader
  yarn add -D @types/storybook__react
  1. Create a .storybook directory and add config.js file

  2. Create storybook script in your build system

    • In our case, this is npm.
      • In package.json write script "storybook": "start-storybook -p 6006 -c .storybook
  3. Configure the storybook config file with the following script:

    import { configure } from "@storybook/react"
    // This will iterate through src
    // looking for any extension that matches stories.ts
    const req = require.context("../src", true, /stories.ts$/)
    function loadStories() {
      req.keys().forEach((file) => req(file))
    configure(loadStories, module)
  4. For Storybook to work with TypeScript, create a custom webpack config inside at


    module.exports = ({ config }) => {
        test: /\.(ts|tsx)$/,
        use: [
            loader: require.resolve("awesome-typescript-loader"),
      config.resolve.extensions.push(".ts", ".tsx")
      return config
  5. Create tsconfig


  "compilerOptions": {
    "outDir": "build/lib",
    "module": "commonjs",
    "target": "es5",
    "lib": ["es5", "es6", "es7", "es2017", "dom"],
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDirs": ["src", "stories"],
    "baseUrl": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "declaration": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  "include": ["src/**/*"],
  "exclude": ["node_modules", "build", "scripts"]

PieChart Component

  1. Create a chart component under src/components named PieChart.ts

     import * as React from "react"
     const PieChart = () => {
     	return ...
  2. Import the pie chart component from @nive/pie

    import { ResponsivePie } from "@nivo/pie"
  3. Use the component within the PieChart component we created

  4. Create a chart component under src/components named PieChart.tsx

     import * as React from "react"
     import { ResponsivePie } from '@nivo/pie'
     const PieChart = () => {
     	return (
  5. Define data to be used in pie chart

     import * as React from "react"
     import { ResponsivePie } from '@nivo/pie'
     	Required props are: { data }
     	Parent element is required to have width and height
     	when using responsive chart components
     	data type is Array<{
            id:    string | number,
            value: number
     const PieChart = (data) => {
     	return (

Storybook Component Setup

  1. Create an pie_chart.stories.tsx file next to the PieChart.tsx component file

    import * as React from "react"
    import { storiesOf } from "@storybook/react"
    import { PieChart } from "./PieChart"
     	Stories are to demonstrate the capabilities of a component
     	In this instance, we will need to supply data to the pie chart
    storiesOf("PieChart", module).add(
      "Demonstrate simple data passed to chart",
      () => {
        ;<PieChart data={{ exampleData }} />

To run storybook : npm run storybook



yarn add react-fetching-library
  1. Create the directory src/client

  2. Create the file api.ts

    and setup to use library:

    import { createClient } from "react-fetching-library"
    // Often the host endpoint would be hidden in evironment variables
    export const requestHostInterceptor =
      (host) => (client) => async (action) => {
        return {
          endpoint: `${host}${action.endpoint}`,
    export const Client = createClient({
      requestInterceptors: [requestHostInterceptor(HOST)],
  3. Create the query action in


export const fetchData = {
  method: "GET",
  endpoint: "/",
  1. Create the client provider component and suspense wrapper


     import { ClientContextProvider } from 'react-fetching-library';
     import { Client } from './api/Client';
     const App = () => {
       return (
         <ClientContextProvider client={Client}>
    		<Suspense fallback={<ProgressSpinner />}>
    			{// Whatever children need the client>}
  2. Create container component for chart component to handle the query for data


     import { useQuery } from 'react-fetching-library';
     import { fetchData } from '../client/actions'
     export const ChartContainer = () => {
     	const { loading, payload, error, query } = useQuery(fetchData)
     	if (error) return <ErrorButton onClick={query}/>
     	// Will add some data transformation step here
     	return <PieChart data={transformedData} />

Data transformation Utility

  • The incoming data from Treehouse is not the correct shape and we need to transform it into a usable shape for the UI
  1. Create the directory src/util

  2. Inside that directory, create the file fetchData_util.ts

  3. Create a function in the file that takes json data of this shape:

     	"name": "Beavis"
     	"points": {
     		"total": 12345,
     		"javascript": 2345,
     		"ruby": 0,

    and produces data of this shape:

         "id": "javascript",
         "label": "javascript",
         "value": 2345,

    Removing the "total" and any data with the value of 0

  4. Use this utility function within the component that fetches the data

    import { useQuery } from "react-fetching-library"
    import { fetchData } from "../client/actions"
    export const ChartContainer = () => {
      const { loading, payload, error, query } = useQuery(fetchData)
      if (error) return <ErrorButton onClick={query} />
      const transformedData = transformData(payload)
      return <PieChart data={transformedData} />
  5. Create the directory tests

  6. Create the file tests/fetchData_test.js

  7. Write some tests considering all possibilities for the utility function

    describe("Confirm transformData", () => {
      test("Should remove key of total from remote data")
      test("Should remove objects with value of 0")


  1. Create the spinner component under the components directory
  2. Should be a simple emoji animated to spin with css animations
  3. Use as the suspense fallback


There were a few surprises when implementing this. Some were in Storybook while getting it set up. After following the documentation rather than a tutorial, I got it to work properly.

The other more frustrating surprise was that the client library I used makes an OPTIONS request with every GET request and the Treehouse server was not playing along. I would receive a 500 error on the OPTIONS request, then never get to a successful GET request. By using Postman, I could confirm a GET would work fine without the OPTIONS request. The client library didn't have a way to configure the fetch to drop the OPTIONS request so I ended up creating a node server to be a proxy to the data. The node server made the same GET request, then passed it along to my app. 3 hours later, problem solved.



Storybook seems like an awesome tool to help guide the design of components. I see a cost in learning how to use it and the time spent in designing a component. One could easily burn hours designing a single component. I enjoy Storybook's workflow of isolating a component and its influence on making decisions of a components API. I look forward to learning more about this tool.


This library is newer (2 months old as of writing this!) but I have really good feelings about it already. The docs are well written and very helpful. The composability is great from my perspective. After they work out a few kinks, it could be a great tool for componentized fetch requests.


I chose Nivo for charting mostly because their site is pretty. The documentation is really great as well. This being the first time using it, I thought it was rather easy to get started and figure out how to plug it into my project. A lot of the styling of charts is handled for you, and some may consider that a plus or a minus, but most of it is customizable. It's no D3 ;) but being the react nerd that I am, I found it to be quite an easy and visually pleasing way to jumpstart charts in my project. I look forward to using this library in the future.

Tech designs

As mentioned, part of this weekend activity was to practice technical designs. Our principal engineer wrote a post on the importance of technical design that goes more in-depth on its value. After using this approach for my weekend hacking extravaganza, I saw how it definitely kept my head out of the details of the code and focused on the bigger picture. After getting together a "template" to follow, implementing the code went rather quickly, then much of the time was spent debugging smaller problems.

This project was admittedly an overuse of libraries and tools, but I now have a functioning template to create charts using React, Nivo, and Storybook.


  • Storybook seems great for large projects that have many reused components.
  • Nivo makes very pretty charts. Great documentation. Understandable API.
  • React-fetching-library has great composability. It is young but has great potential.
  • Creating a technical design greatly increases the speed of development and reveals the difficult parts sooner.

Repos can be found here:

Treehouse Chart

Treehouse Profile Server

Interested in working with us?