Creating a React Component Library With Typescript Using Styleguidist

How to build a reusable component library, publish and automate the release flow

Sidney Barrah
The Startup
12 min readJul 12, 2020

--

One of the beauties of React is component reusability, which is a huge time saver. Most times, creating new components for a project may mean that you may have to do the same for every new project which will ultimately result in unavoidable code duplication.

Having a component library ensures that reusable components can be packaged and shared across multiple applications, meaning that you do not have to worry about code duplication, makes it faster to build new applications and helps speed up scalable application development. Components can easily be customised at the project level for each application they belong to. It also means that issues such as bug fixes and adding new features can be done at source and pulled through on every project that needs it.

In this post, I explain how to create a React component library using the following tools:-

Development

Create a new React project with CRA using npx for the latest version

The next step is to install dependencies required by our project:

Configuration

After installing all dependencies, you should create a configuration file for babel babel.config.js at the root of your project and add the following:

Next, we need to add a configuration file for React-styleguidist, styleguide.config.js at the root of your project and add the following:

You can find out more about React-Styleguidist configuration.

Documentation

We need to add some documentation for our library. In this case, I create a docs folder at the project root and create an introduction.md file

And added some content about our library:

Theme

The next step is for us to create a theme for our project. You can create as many project specific themes as you want, especially if your have multiple projects that need to use different styles.

For this demo, I will be creating a theme for a project1 with specific and shared theme functions.

First we create our theme folder, then create files for our theme functions and our ThemeProvider high order component:

Modify the color.ts file

Next, modify the fontSize.ts file

Also, modify the shared fonts fontFamily.ts file

And, add some custom breakpoints in breakpoint.ts

We need to export our project themes:

We can specify and customise which themes we want for each project.

Next, we export our ThemeProvider.ts

Styleguide

We also need to define a layout for our Styleguide. So, we create a ThemeWrapper component to serve as a top level wrapper component and customises the layout.

And we enter the following:

The ThemeProvider component accepts a theme prop, which it passes it down to all child components.

Next, we modify our styleguide.config.js and update the styleguideComponents prop to our new ThemeWrapper component, enabling a customised layout:

Next we modify the script commands in our package.json file

Running yarn run styleguide will start the style guide dev server, while yarn run styleguide:build builds a production-ready HTML version.

Components

In structuring the components, I have adopted the Atomic Design system proposed by Brad Frost.

We modify Text.tsx atomic component as follows:

Next, we modify RichText.tsxatomic component

Next, we create our Section.tsx molecule component. Molecules are a combination of two or more Atomic components

Styleguidist handles documentation using the JSDoc comment blocks in the components and also picks up props from each propTypes declaration and displays them in a table.

To view the styleguide library locally, we run yarn run styleguide to start styleguide dev server and we can view it at http://localhost:6060/

React Component Library styleguide

We can see our Introduction but not our new components.

This is because Styleguidist will look for a README file such as a Readme.md or Text.md or RichText.md within the respective components folder in order to display them. You can read more about Styleguidist documentation.

We need to create README files for our new components:

Then add a few examples such as the following to the Text.md:

And alsoRichText.md

After a hot reload, Styleguidist will generate the components from the markup:

RichText components
Text components
Section.tsx

Testing

Styleguidist uses Jest with Enzyme for testing.

To add tests to our library, we need to install some dependencies:

Next, we need to add some tests for our components. First, we create a higher order shallow wrapper component:

Update the shallowWithTheme component as follows:

Next, we create our test files

And we enter the following to theText.test.tsx , RichText.test.tsx and Section.test.tsx files:

We need to update our package.json with our test commands:

Running yarn run testwill run the full suite of tests; yarn run test:watch watches test files for changes, yarn run test:update updates our tests and yarn run test:no-warnings runs tests in silent mode.

Linting

It is important to have a clear and consistent coding convention. ESLint makes it possible to identify, report and fix any inconsistencies and bugs in our code during development.

To add linting to our project, we need to install a few dependencies:

We also installed Prettier which forces code formatting; Lint-staged which ensures that linting is run on files before they are committed; Husky which helps makes git hooks easier.

We then need to set up a configuration file for ESLint:

ESLint init

This generates a configuration file .eslintrc.js. I have added some modifications with our plugins and rules:

Next, we need to create an .eslintignore file which tells ESLint which directories or files to ignore and add the following:

Next, we need to also update our package.jsonfor by adding our lint command to the script field and adding new fields for husky and lint-staged :

We can run yarn run lintto lint test our files. Also, every changed file to will also be lint tested before it is committed.

Husky — pre-commit

Production

In order to use our library as npm module, we need to export our themes and components and compile our typescript files into plain Javascript before we can publish as a module and import into our projects.

First, we create our export file src/index.ts and add the following:

Next, we need to install the following modules :

And update our script field inpackage.json with our postinstall and build command.

This means that everytime we run yarn install, the build command will be triggered, creating a new build of our project. Next, we also need to modify our Typescript configuration file tsconfig.json to specific our source foldersrc and compiled destination dist folder and also which directories or files to exclude from typechecks.

Next, we run yarn run build to generate compiled javascript files in the destination dist folder.

We also need to run yarn run styleguide:build to generate a production-build of a HTML-static library in the styleguide folder. Your project structure should now look like this:

React Component Library project structure

Next we updatepackage.json by adding new fields to point to the compiled source as below:

Publishing

Next, before we can publish our library, we need to also create a .npmignore file, which tells NPM which directories or file to ignore. We then add the following:

And we can run npm publish , which publishes the library on NPM. You need to have an account on NPM before you can publish. If you don’t have an account, you can create one and it is free. Also, the name of your library / module must be unique on NPM. In this case, I named the library rcl-demoon NPM.

Continuous Integration and Development, Versioning and Publishing

Next, we automate our builds, tests and deployments using Github and CircleCI . You can read more about how to set up CircleCI and what Continuous Integration and Development means. You can choose whichever CI/CD platforms you prefer.

First, we push our remote repository on Github and then look for and set up the project on the CircleCI Dashboard.

CircleCI Dashboard

I have opted to manually add the configuration file .circleci/config.yml to my project:

We will also be using Semantic Release to automate version management and publishing of our package to NPM. To do that, we need to install the module and it’s CLI:

By default, Semantic Release expects commits to be in the conventional GIT commit format likefeat: add feature X or fix: fix bug Y that perform minor and patch version bumps respectively.

The CircleCI configuration is triggered on every push to the remote repository on GitHub and this also triggers a release as a part of the workflow:

Next, we need to setup our authentication tokensGH_TOKEN/ GITHUB_TOKEN and NPM_TOKEN environmental variables in the CircleCI project setup. Read Creating a personal access token on how to create an access token on GitHub. Also, you need to have an account on NPM to create an access token.

CircleCI Project settings

After renaming the library to rcl-demo , we trigger another deployment

CircleCI Pipeline

We also need to update the README.md file as below:

NPM — React Component Library

Usage

To use our library in any project, we simply need to install by running yarn add rcl-demo or npm install rcl-demo .

Next we need to import the. ThemeProvider and theme as a high order component wrapper in our application:

And we can import any component and use anywhere in the project

Preview

To deploy the static pages on Netlify, you need login / signup and import the project from Github. Next, we need to update the build command and publish directory

Netlify — Build settings

Clicking on theDeploy site button should trigger the deployment:

With Netlify, you can also customise the settings for the static site and domain.

As soon as deployment is finished, we can preview our static library:

React Component Library — Netlify

Conclusion

Having a component library is definitely the way to go if you want to have sharable and reusable components and prevent code duplication across different projects. It also means we can also fix bugs or add new features to our components with less effort.

There are various frameworks that also help create your own system or provide you with reusable components right out-of-the-box like Material UI, React Bootstrap, Fluent UI and Semantic UI.

I have included the Github repository with the current implementation in this article. Feel free to clone, fork or star it if it helps you.

Further Reading

--

--