How to create your own React Components library
Tags: javascript, tutorial, typescript, react
Published: 2022-08-18 12:15:00

Are you curious about how to create your own components library on React + Typescript?

In this set of articles we will go through such aspects as: setup project structure, writing a small component, testing, connecting to storybook, deploying project to GitHub Pages and pushing a package to NPM. Let's start by setting up a project!

## Set up

We will use a [TSDX library](https://tsdx.io/) - this tool is something similar to create-react-app, but for creating components library. It allows as to initialize a project immediately with already set up bundler, Rollup with Typescript supporting, testing with Jest, code formatter, Prettier and Storybook.

To start, run this command in your terminal with your library name

```
npx tsdx create fancy-react-lib
```
Choose a template `react-with-storybook` - it is a React package with necessary development dependencies and @types installed, with [React Storybook](https://storybook.js.org/) already setup as well

![Choose a TSDX template](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lhoyu6vv5tvmlwkoxnjg.png)

Now we can open a generated project and browse the structure. The first folder is `GitHub workflows`. The First of them - `main.yml`, it runs linting, tests and builds the project. The main goal is to check that the project is building successfully in different operating systems and node versions. Some dependencies require `node` version 14 and upper, so let's update this part of the file:

```
    strategy:
      matrix:
        node: ['14.x', '16.x']
        os: [ubuntu-latest, windows-latest, macOS-latest]
```

The next - `size.yml`. It uses action `size-limit` to get a final bundle size and push it to pull request. Also, it rejects a pull request if the size is higher than the limit, that was mentioned in `package.json`.

```
  "size-limit": [
    {
      "path": "dist/react-super-library.cjs.production.min.js",
      "limit": "10 KB"
    },
    {
      "path": "dist/react-super-library.esm.js",
      "limit": "10 KB"
    }
  ],
```

We also have next folders in our project:
- storybook
- example (it is a playground, but we will use storybook for these purposes)
- src (we will place our components here)
- stories (here will be our stories for storybook)
- test

In general, this is all that we need to know about the project structure. Now we can init a git repository and push it to GitHub.

It's time to create the first piece of code!

## Creating a component

Let's start with the button component.

Create a `Button` folder in `src`, then create a `Button.tsx` file.

Nothing complicated, just standard HTML `button` and several props: onClick, children (ReactNode - it is a type including React Element, string, number, whatever), isDisabled, variant (to use different styles, let's start with `primary` and `success` variants). 
{% embed https://gist.github.com/alpavlove/804ad309b176511ed264aa83b7c41226.js %}

## Styling

You can use any approach to adding `CSS styles`, that you like. I will show the easiest way - just add a CSS file for our component. Create a `Button.css` in `src/Button` folder and paste styles below

{% embed https://gist.github.com/alpavlove/9a6d6aae2241ba305f245d10e7cebae8.js  %}

We want bundler to provide styles as separate CSS file, for that we need to change Rollup settings bit. 

Run this command and follow [TSDX customization ](https://tsdx.io/customization#rollup)instructions

```
yarn add -D postcss rollup-plugin-postcss autoprefixer cssnano

```

Create a `tsdx.config.js` file in the root directory and past this code

{% embed https://gist.github.com/alpavlove/7c6d0a933af1a42b66b9d89e5c9ced71.js %}
 
## Storybook

Let's create a story for our button! We already have a default story in the `stories` folder, so we can create the same one. Create a new file `Button.stories.tsx` in `storybook` folder

{% embed https://gist.github.com/alpavlove/5888ac24d01c38bba06f3b8ee63b5dcc.js %}

To build storybook locally, run this command:

```
 yarn storybook
```

The last but not least, let's export the Button component in  src/index.js file - the entry point of our package. 

```
export * from './Button/Button'
```

Cool! We can check that storybook is working.

Hope it was helpful. The project files you can find also in a [GitHub repo](https://github.com/alpavlove/fancy-ui-reat-lib).