Originally posted on my personal blog
After developing projects with React.js for some time, I’ve noticed that some of my own custom components I use in different projects. Up until now, I’ve used “good ol’ copy-paste method” to share these components between projects. But now I think I’m old enough to publish my own components to npm and then import them into my projects.
So, after browsing the internet for a couple of hours and trying to publish my React component “the hard way” (with manual webpack and babel configuration and so on), I’ve found a great tool -
create-react-library - CLI for easily creating reusable react libraries. With the help of this package, I’ve published my custom React component fast and painless.
Prerequisites
I assume that if you are going to make your npm package, you already have installed node and npm. If not, you can download and install it from here.
Also, you need an npm account. If you don’t have it, please sign up here.
Let’s start creating our npm module!
First of all, you need to come up with the name of your package and make sure that it’s available. Go to https://www.npmjs.com/ and check it through the search bar.
Open your terminal, go to the directory, where you are going to create your package and enter the following command:
npx create-react-library <name of your package>
I’m going to publish my custom Progress Bar React component. So I enter the command:
npx create-react-library react-pg-bar
You will be prompted to ask a few questions about your package. Here are my answers:
As a package name, I’ve entered @ramonak/react-progress-bar. This is so-called the scoped package. By adding @ you can group your packages and also use any package name that might be already taken.
After create-react-library finishes creating the skeleton of our module, we have the following project structure:
This project contains ExampleComponent in the src folder and its example showcase in the example folder. But the main beauty of it is that all necessary configuration for publishing to NPM is already done for you.
As recommended by create-react-library docs, it’s better to open two terminal windows (or tabs). In the first one, run rollup to watch your src/ module and automatically recompile it into dist/ whenever you make changes.
cd <your_folder_name> && npm start
In the second one, run the example/ create-react-app that's linked to the local version of your module.
cd <your_folder_name>
cd example && npm start
That’s how the Sample component looks like:
The folder, where we are going to add code of our component is src. I’m going to replace the code of the Sample component in index.js file on the code of my Progress Bar component.
import React from "react";
const ProgressBar = props => {
const { bgcolor, completed } = props;
const containerStyles = {
height: 20,
width: "100%",
backgroundColor: "#e0e0de",
borderRadius: 50,
margin: 50
};
const fillerStyles = {
height: "100%",
width: `${completed}%`,
backgroundColor: bgcolor,
transition: "width 1s ease-in-out",
borderRadius: "inherit",
textAlign: "right"
};
const labelStyles = {
padding: 5,
color: "white",
fontWeight: "bold"
};
return (
<div style={containerStyles}>
<div style={fillerStyles}>
<span style={labelStyles}>{`${completed}%`}</span>
</div>
</div>
);
};
export default ProgressBar;
As I don’t use a separate css module for styles, I can delete styles.module.css file. Of course, it depends on the component which files you need to use. Just remember to keep the entry point of your component (where you are exporting your module) in the src/index.js file.
Next, we have to test that our component is working. For that, we go to the example/src/App.js and replace the code there on the code of the app which will demonstrate your component. This is the code of my demo app:
import React, { useState, useEffect } from "react";
import ProgressBar from "@ramonak/react-progress-bar";
import "@ramonak/react-progress-bar/dist/index.css";
const App = () => {
const [completed, setCompleted] = useState(0);
useEffect(() => {
setInterval(() => setCompleted(Math.floor(Math.random() * 100) + 1), 2000);
}, []);
return (
<div className="App">
<ProgressBar bgcolor={"#6a1b9a"} completed={completed} />
</div>
);
};
export default App;
Notice, that create-react-app automatically creates an import of your package (just don’t forget to change the name of the imported component) and it’s styles (as I don’t have a separate file for styles I can delete this import). So you don’t have to manually create links to your local package to test it.
Open the browser and see the demo app:
If you are not going to create a public and just use the package by yourself, you can skip the following part and go straight to Publishing
But if the package is public, meaning other developers can use it, then there are some other things we should take care of before publishing.
One of the most important criteria of the usability of a public package is its documentation. So edit README.md file at the root of the project. By default, there is a minimum required information added: how to install and use your package. Feel free to add there whatever you think should be there. There are tons of published npm packages, so the array of readme templates is quite big.
Also, don’t forget to push the code to the GitHub repo which you provided while running npx create-react-library.
And it’s cool to have a demo page where you showcase your component. The simplest way to do this is by publishing your app from example/App.js to GitHub pages simply by running
npm run deploy
and the create-react-library will do all the work.
Publishing
Well, finally, let’s publish our component to npm. Just run
npm publish
If you are publishing a scoped package, but want it to have a public access, run the command
npm publish --access=public
And that’s it! If everything went as planned, you’ll get an email notification that your component was successfully published to npm.
Conclusion
As you can see, publishing your package to npm is really simple when using a great tool like create-react-library.
The complete source code of the @ramonak/react-progress-bar component is in this GitHub repo. Published npm package is here.
Top comments (9)
After the completion I tried to import the module and got this error
registry Using stale data from registry.npmjs.org/ because the host is inaccessible -- are you offline?
npm WARN registry Using stale data from registry.npmjs.org/ due to a request error during revalidation.
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: test@0.1.0
npm ERR! Found: react@15.7.0
npm ERR! node_modules/react
npm ERR! react@"^15.0.2" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.0.0" from @codehat/react-loader@1.0.0
npm ERR! node_modules/@codehat/react-loader
npm ERR! @codehat/react-loader@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\manoj\AppData\Local\npm-cache\eresolve-report.txt for a full report.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\manoj\AppData\Local\npm-cache_logs\2021-07-04T03_13_04_581Z-debug.log
Hi coder, thanks for the tutorial. I have a problem uploading my component to npm, does not allow me to use '@' npm ERR! 403 a package version that is forbidden by your security policy.
The name package.json is "name": "@berserk/react-clock" :/
Have you just created your NPM account? If yes, have you verified your email address?
Thanks bro
need to run npm adduser
it doesn't support named export
what about updating the library ?
just change the code of your library, update the version in the package.json file and publish it again
thank you