Publishing a React component package on npm
Tags: react, javascript, webdev, npm
Published: 2020-08-02 23:01:07

Recently at work I had to create and publish a React component on npm, which is planned to be used in multiple projects with little functionality or styles changes.

Due to being a company project, I can't share the source code, but I will share some important snippets as needed.

### It isn't as easy as expected 😕

When I was asked to do such task, we already had the component built and working as a `create-react-app` project, which was also a website and stuff.

I thought it would be as simple as running `npm publish` and that I was going to be able to import it in the other project right away.

Unfortunately it wasn't like that and I ran into compilation issues in the project that implemented it. So I started looking for the _right_ way to do it.

### Meet `create-react-library` 🤓

While searching how to achieve that, I came across with [`create-react-library`](https://github.com/transitive-bullshit/create-react-library).

I was looking for the simplest approach to do what I needed, and didn't want to deal with `webpack` or `babel` stuff and whatnot, so that project definitely came in handy because it was easy to use and pretty straight forward.

### Using `create-react-library` 👨🏼‍💻

Creating a library project is as easy as running
```bash
npx create-react-library project-name
```

You will be prompted for some config, similar to `create-react-app`, but once done, you get the project and everything setup to work right away.

I liked it because I didn't have to do much else, and it also comes with an example project inside, that uses your library, so you can test everything will be working properly after you've "published" the package.

Next thing for me was just migrating the component from the previous project to the library project. It was pretty much a copy-paste process with some little refactoring, but nothing significant else.

### The challenges 😬

Despite requiring no configuration, I encountered a couple problems during the process...

##### 1. React Fragments 🖼

I was getting compilation errors for using React Fragments like this `<>{...}</>`, so I changed that to `<React.Fragment>{...}</React.Fragment>` and they stopped... well, kinda.

Then I started getting `ReferenceError: Fragment is not defined` errors. It wasn't easy to solve so I asked for help in the [Unicorn Utterances](https://discord.gg/FMcvc6T) discord server, and [Corbin](http://crutchcorn.dev/) found [an issue](https://github.com/transitive-bullshit/create-react-library/issues/243#issuecomment-653525598) in the `create-react-library` repo that mentioned adding `--jsxFragment React.Fragment` to the `build` and `start` scripts.

And then it was all working again.

##### 2. Included SVGs 📐

The component included an SVG (the company logo), imported and used something like this:
```javascript
import CompanyLogo from './company-logo.svg'
...
return (
  ...
  <img src={CompanyLogo} alt={'Company Logo'} />
  ...
);
```

It worked fine locally, even with the local project that imported the component library, but after published in npm and imported in the other project, compilation failed, because the svg file was "compiled" with a different name, similar to `company-logo~aBcDe.svg`. Notice the `~` character. That was the issue, because it can't be used in JS var names.

The quick solution, was to make it a prop and allow passing it to the component, so it wasn't compiled by the library but the other project. Again, I didn't want to deal with `webpack` or `babel` or any extra config, so this was the easiest for me.

##### 3. CSS 🎨

I was using css modules for the library components, but I also needed a little of normal css, because the component used other components from [`rmwc`](rmwc.io), and they use that and I needed to override a few styles.

From what I understood `create-react-library` the normal css and the module css files would coexist and work along normally, but for some reason, it wasn't like that, and the normal css was still compiled as a module, i.e. the compiled classes names would have some random suffix to make them unique, and therefore none of the overriden styles were applied.

At the end, I ended up changing the css modules to normal css, so no suffix was added during compilation, and then it all worked as expected.

### Closing up 👋🏼

So, after struggling with those few things, I was able to use the component from the library without any other issues, and everything was working as expected, including react hooks like `useContext` and `useReducer`.

Also, `create-react-library` definitely allowed publishing the package by just running `npm publish` as I wanted it to be.

There are probably other approaches to build a react component(s) package, but this one worked for me and was easy to use, so I liked it and wanted to share my experience.

If you have further questions, I'll try to answer.
Find more about me @ [jahir.dev](https://jahir.dev)

Special thanks to [Corbin Crutchley](http://crutchcorn.dev/), [Alex Dueppen](https://ajd.sh/) and Robert Mennell from the [Unicorn Utterances](https://discord.gg/FMcvc6T) discord server, who helped me solve the issues and get the library working.

Cover image is from [unsplash.com](https://unsplash.com/photos/FkjaN-7gWC0)