How to publish your React component on npm
Tags: react, npm, component, package
Published: 2020-04-14 14:04:28

> This tutorial is for the more experienced React developers. If you’re just looking to learn how to build a [React app](https://reactjs.org/), there are tons and tons of tutorials available online!

Ok, so you’ve read tutorials, figured out how to set up a React project using `create-react-app`, learned how to install npm packages, and finally created your very own functional React app, and to that that I say congratulations!

![alt text](https://miro.medium.com/max/1400/1*o6QbQCwuPjbSTS6NJhhtSg.png "Congratulations")

As you go on your journey of creating your apps, you will undoubtedly come across some cool open source npm packages that made your development easier, whether it be [material-ui](https://www.npmjs.com/package/@material-ui/core), [react-router](https://www.npmjs.com/package/react-router-dom), or [react-spinners](https://www.npmjs.com/package/react-spinners). Heck, chances are you might’ve even come up with some of your own cool React components! And now you’re wondering, how might I share that with the rest of the world?

* * *

Packaging your React component
==============================

Before publishing anything to npm, the first step is to put your component files into a nice, clean package. I’ve created a template to make everything easier to follow, go ahead and [download this](https://github.com/Groftware/template-reactnpm) first. And once you’re done, open the folder in your favorite code editor.

![alt text](https://miro.medium.com/max/900/1*Qj35PGdY8C59bxibYig6Yg.png "Visual Studio Code")

my favorite one is definitely [Visual Studio Code](https://code.visualstudio.com/)

1\. Adding your React component
-------------------------------

The first thing you’re gonna wanna do is to move your React component files into the `/src` folder. For the purpose of this demonstration, I’ve created a component called `MyCoolButton.js` . Make sure to also include all the files that are required by your component. In this case, I‘ve also added in `MyCoolButton.css` .

![alt text](https://miro.medium.com/max/1128/1*6f3MFY2r2ZYHb5VkcP33pA.png)

Add your component files into /src folder

2\. Sort out dependencies
-------------------------

The next thing you have to do is to figure out if your component requires any other dependencies. You can find that out by opening up your component file and check if it imports any other dependencies. In this case, my component requires the dependency `prop-types` .

```
// This component also requires 'react',
// but it has already been included in the
// list of dependencies in package.json
import React from 'react';

// This component requires prop-types
import PropTypes from 'prop-types';

import './MyCoolButton.css';

const MyCoolButton = ({ type, title, onClick }) => (
  <button
    type={type}
    className="container"
    onClick={onClick}
  >
    {title}
  </button>
);

MyCoolButton.propTypes = {
  title: PropTypes.string.isRequired,
  type: PropTypes.string,
  onClick: PropTypes.func,
};

MyCoolButton.defaultProps = {
  type: 'button',
  onClick: () => {},
};

export default MyCoolButton;
```

Now let’s open up `package.json` , and add the dependencies in. Normally you would add your dependencies under `dependencies` , but in this case, you have to add them into `peerDependencies` and `devDependencies` . This is how your `package.json` should look like. Notice that the list of dependencies is empty

```
{
    "name": "YOUR_PACKAGE_NAME",
    "version": "0.0.1",
    "description": "",
    "main": "./lib/YOUR_COMPONENT.js",
    "license": "MIT",
    "scripts": {
        "build": "webpack"
    },
    "peerDependencies": {
        "prop-types": "^15.6.0",
        "react": "^16.0.0",
        "react-dom": "^16.0.0"
    },
    "devDependencies": {
      "prop-types": "^15.6.0",
        "babel-core": "^6.21.0",
        "babel-loader": "^7.1.4",
        "babel-preset-env": "^1.6.1",
        "babel-preset-react": "^6.16.0",
        "babel-preset-stage-0": "^6.24.1",
        "css-loader": "^3.5.1",
        "path": "^0.12.7",
        "react": "^16.0.0",
        "react-dom": "^16.0.0",
        "style-loader": "^1.1.3",
        "webpack": "^4.5.0",
        "webpack-cli": "^3.2.1"
    },
    "dependencies": {}
}
```

After that, run `npm install` (or if you use [yarn](https://yarnpkg.com/), `yarn install`) to install the required dependencies.

3\. webpack.config.js
---------------------

Next up, we’ll use Webpack to bundle our React components into a nice CommonJS module. [Click here](https://webpack.js.org/) to learn more about Webpack and what it does. Let’s start by opening up `webpack.config.js` .

```
const path = require('path');

module.exports = {
  mode: 'production',
  entry: './src/MyCoolButton.js',
  output: {
    path: path.resolve('lib'),
    filename: 'MyCoolButton.js',
    libraryTarget: 'commonjs2',
  },
  module: {
    rules: [
      {
        test: /\.js?$/,
        exclude: /(node_modules)/,
        use: 'babel-loader',
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      }
    ],
  },
  resolve: {
    alias: {
      'react': path.resolve(__dirname, './node_modules/react'),
      'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
    }
  },
  externals: {
    // Don't bundle react or react-dom      
    react: {
      commonjs: "react",
      commonjs2: "react",
      amd: "React",
      root: "React"
    },
    "react-dom": {
      commonjs: "react-dom",
      commonjs2: "react-dom",
      amd: "ReactDOM",
      root: "ReactDOM"
    }
  }
};
```

This is the file that contains the different configurations that Webpack will use to bundle your React component. Here’s a description of the important settings:

`entry` — This refers to your React component. You should change it to the component that you’ve added in **Step 1**.

`output` — This specifies the path to the output file. You should update the `filename` to match your component’s file name.

`module.rules` — This is an array of rules that we are applying to our module. The first rule looks for any `.js` file and tries to [transpile](https://scotch.io/tutorials/javascript-transpilers-what-they-are-why-we-need-them) it using `babel-loader` . However, the second rule is only relevant if your component uses `css` . If your component uses any `css`, you will have to add this in. Click here to find out more about `[css-loader](https://webpack.js.org/loaders/css-loader/)` and `[style-loader](https://webpack.js.org/loaders/style-loader/)` .

> **Important Note**
> 
> If your component uses `.sass` or`.scss` , you would have to also include `[sass-loader](https://webpack.js.org/loaders/sass-loader)` by adding it to your Webpack module rules as well as adding it to your list of `devDependencies` in `package.json` . [Click here](https://webpack.js.org/loaders/) to see a list of loaders that you might need to use.

I have only gone through the options that are relevant to this tutorial. Check out the full list of options [here](https://webpack.js.org/configuration/).

4\. Bundle em’ up
-----------------

Run `npm run build` (or if you use yarn, `yarn build`). This should generate a folder called `/lib` which contains your freshly packaged component, in this case, `MyCoolButton.js` .

5\. Test your component
-----------------------

Before you publish it to the world, it would make sense to take your package for a test drive first (or if you’re absolutely confident that it will work, feel free to skip ahead to **Publishing To NPM**).

Run `npm pack` . This will generate a `.tgz` file at the root directory.

Open up any React application that you want to test your new package, and then run `npm install path_to_tgz_file` . Replace `path_to_tgz_file` with your actual path.

In my case, the whole command looks like this: `npm install /Users/Groftware/mycoolbutton/mycoolbutton-0.0.1.tgz` .

The next thing you do is just import the component and use it normally

```
import React from 'react';  
import MyCoolButton from 'mycoolbutton';function App() {  
 return (  
    <div>  
      <MyCoolButton title="Click Me!"/>  
    <div>  
  )  
}export default App;
```

Does it work? Great! Let’s move on to actually publishing it to the world.

Publishing to NPM
=================

Alright so now you have your `/lib` folder with your newly packaged component ready to go, the next thing to do it just publishing it to npm.

Run `npm login` and login with your npm account. Create one [here](https://www.npmjs.com/signup) if you don’t already have one.

After you’re logged in, the final thing to do is `npm publish` , and you’re all set!

* * *

Links
=====

Tutorial Template and complete example
--------------------------------------

*   [Template](https://github.com/Groftware/template-reactnpm)
*   [Full example](https://github.com/Groftware/MyCoolButton)
*   [Published npm package](https://www.npmjs.com/package/mycoolbutton)

React
-----

*   [https://reactjs.org/](https://reactjs.org/)

Npm
---

*   [https://www.npmjs.com/signup](https://www.npmjs.com/signup)
*   [https://www.npmjs.com/package/@material-ui/core](https://www.npmjs.com/package/@material-ui/core)
*   [https://www.npmjs.com/package/react-router-dom](https://www.npmjs.com/package/react-router-dom)
*   [https://www.npmjs.com/package/react-spinners](https://www.npmjs.com/package/react-spinners)

Yarn
----

*   [https://yarnpkg.com/](https://yarnpkg.com/)

Webpack
-------

*   [https://webpack.js.org/](https://webpack.js.org/)
*   [https://webpack.js.org/loaders/css-loader/](https://webpack.js.org/loaders/css-loader/)
*   [https://webpack.js.org/loaders/style-loader/](https://webpack.js.org/loaders/style-loader/)
*   [https://webpack.js.org/loaders/sass-loader](https://webpack.js.org/loaders/sass-loader)
*   [https://webpack.js.org/loaders/](https://webpack.js.org/loaders/)

* * *
Enjoyed or found this helpful? Checkout my other articles [here](https://medium.com/groftware). Thanks!