How I'm starting my React apps now

Reading time ~3 minutes

tl;dr, clone


For this setup, I have node v6.9.1 installed. This uses create-react-app to create the base project, and then walks through various things I usually want for a React project, like my preferred editor configuration (for VS Code) for the project, Wallaby.JS, Prettier, and Storybook.

npx create-react-app my-react-app
cd my-react-app
npm i

Validate that the app starts

npm start
open http://localhost:3000 # the app should do this for you

You should see a “Welcome to React” message, logo, etc in your web browser.

Configure Wallaby.js

Grab the Wallaby.js configuration file and save it as “wallaby.js” at the top level of the project.

Editor configuration

  1. At the top level of the project, add the following to a “.editorconfig” file:

     indent_style = space
     indent_size = 2
  2. Add extensions to the extensions.json for the workspace (e.g. in .vscode/extensions.json)

       // See
       // for the documentation about the extensions.json format
       "recommendations": [
         // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
  3. Then go install those if you don’t already have them.

  4. Make vscode apply formatting for this workspace, add this to .vscode/settings.json

       "editor.formatOnSave": true,
       "editor.formatOnType": true

Setup prettier

Install prettier and an eslint configuration:

npm i --save-dev --save-exact prettier
npm i --save-dev eslint-config-prettier

Add a .eslintrc.json file to the top level:

  "extends": ["prettier", "react-app"]

Setup storybook

  1. Install it

     npm i --save-dev @storybook/react
  2. Add an entry to package.json scripts:

       "scripts": {
         "storybook": "start-storybook -p 9001 -c .storybook"
  3. Set up an initial config in .storybook/config.js

     import { configure } from '@storybook/react';
     function loadStories() {
         // You can require as many stories as you need.
     configure(loadStories, module);
  4. Install Storybook add-ons

     npm install --save-dev @storybook/addon-storyshots @storybook/addon-actions  @storybook/addon-a11y @storybook/addon-links @storybook/addon-graphql @storybook/addon-knobs @storybook/addon-notes react-test-renderer
  5. Create .storybook/addons.js

     import "@storybook/addon-actions/register";
     import "@storybook/addon-a11y/register";
     import "@storybook/addon-links/register";
     import "@storybook/addon-knobs/register";
     import "@storybook/addon-notes/register";
  6. Setup storyshots for Jest

    See more about Storyshots and more info about Jest’s snapshot testing.

    Create a new test file with the name Storyshots.test.js (I’m putting it in src/)

     import initStoryshots from '@storybook/addon-storyshots';
         storyNameRegex: /^((?!.*?DontTest).)*$/
  7. Add some stories just to validate that Storybook is working

    Add this to stories/index.js:

    import React from "react";
    import { storiesOf } from "@storybook/react";
    import { action } from "@storybook/addon-actions";
    import { checkA11y } from "@storybook/addon-a11y";
    import { linkTo } from "@storybook/addon-links";
    import { setupGraphiQL } from "@storybook/addon-graphql";
    import { withKnobs, text, boolean, number } from "@storybook/addon-knobs/react";
    import { withNotes } from "@storybook/addon-notes";
    // setup the graphiql helper which can be used with the add method later
    const graphiql = setupGraphiQL({ url: "http://localhost:3100/graphql" });
    storiesOf("button", module)
            "with text",
    Clicking this button will take you to the next story.
    `)(() => (
        <button onClick={linkTo("button", "with some emoji")}>
            Hello Button
        .add("with some emoji", () => (
            <button onClick={action("clicked")}>😀 😎 👍 💯</button>
        .add("Inaccessible", () => (
            <button style=>
                Inaccessible button
            "get user info DontTest",
                user(id: "1") {
        .add("with a button", () => (
            <button disabled={boolean("Disabled", false)}>
                {text("Label", "Hello Button")}
        .add("as dynamic variables", () => {
            const name = text("Name", "Arunoda Susiripala");
            const age = number("Age", 89);
            const content = `I am ${name} and I'm ${age} years old.`;
            return <div>{content}</div>;

Testing the tests

  1. Run the tests
     npm test
  2. If you get an error about “jest-cli”, try deleting node_modules and running “npm install” again. I had to do this.

  3. After it runs, you’ll see a new file: src/__snapshots__/Storyshots.test.js.snap

  4. Start Storybook

     npm run storybook
     open http://localhost:9001  # It will not open this automatically (but it will reload when stories are changed.)

Check out the end result, or try it yourself.

Tin Khan

After five months of working at Saltbox in early 2012, funds ran out. I seriously considered taking a gamble with a work-for-equity offer...… Continue reading

A Comeback for Another Drink

Published on September 25, 2016

Fanonic Update

Published on July 26, 2012