Create and deploy react components to NPM

20. feb. 22

How to Create and Deploy a React Component to NPM

In this guide, we'll walk through the entire process of creating a simple React button component that displays an alert with today's date when clicked. We'll also cover how to test it using the Ladle tool and deploy it to NPM using the tsup bundler.

Basic Project Setup

1. Create a New Project Folder

Start by creating a new folder for your component:

mkdir my-awesome-button-alert-component
cd my-awesome-button-alert-component

2. Initialize the Project

Initialize a new project with npm:

npm init

Fill in the necessary project details.

3. Install Required Dependencies

Install React, TypeScript, and other required packages:

npm i -D react react-dom typescript @types/react @types/react-dom

Your package.json should look like this:

{
  "name": "my-awesome-button-alert-component",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "@irekrog",
  "license": "MIT",
  "devDependencies": {
    "@types/react": "^18.0.12",
    "@types/react-dom": "^18.0.5",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "typescript": "^4.7.3"
  }
}

4. Generate TypeScript Configuration

Run the following command to initialize a TypeScript config file:

tsc --init

Modify the tsconfig.json file to include React support:

"jsx": "react"

Writing the Component Code

5. Create the Component

Create a src/button/index.tsx file with the following code:

import React from "react";
import "./style.css";

export type ButtonProps = {
  title: string;
  className?: string;
};

export const Button = ({ title, className = "" }: ButtonProps) => {
  const onShowAlert = () => {
    alert(new Date().toLocaleDateString());
  };
  return (
    <button
      className={`my-awesome-component ${className}`}
      onClick={onShowAlert}
    >
      {title}
    </button>
  );
};

6. Add Styling

Create a src/button/style.css file:

.my-awesome-component {
  background: #6750a4;
  color: #ffffff;
  border: 0;
  padding: 1rem 2rem;
  font-size: 1rem;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: 0.3s background;
}
.my-awesome-component:hover,
.my-awesome-component:focus-visible {
  background: #432b7e;
}
.my-awesome-component:focus-visible {
  outline: 4px dashed #49454e;
}

Using Ladle for Component Display

7. Install Ladle

npm i -D @ladle/react

8. Create a Story File

Add src/button/button.stories.tsx:

import React from "react";
import { Button } from "./index";

export default {
  title: "Button",
};

export const ButtonPrimary = () => (
  <Button title={"Hello World! Click me to show current date :)"} />
);

9. Add Ladle Script

Modify package.json:

"scripts": {
  "ladle": "ladle serve"
}

10. Run Ladle

npm run ladle

Deploying to NPM

11. Install tsup Bundler

npm i -D tsup

12. Configure tsup

Create tsup.config.json:

{
  "splitting": true,
  "sourcemap": true,
  "clean": true,
  "minify": true,
  "entry": ["src/index.ts"]
}

Create src/index.ts to export the component:

export * from "./button";

13. Add Build Script

Modify package.json:

"scripts": {
  "build": "tsup"
}

14. Define Peer Dependencies

"peerDependencies": {
  "react": "^16.8 || ^17 || ^18",
  "react-dom": "^16.8 || ^17 || ^18"
}

15. Build the Package

npm run build

16. Prepare Package for Deployment

Modify package.json:

"files": ["dist"],
"main": "dist/index.js",
"types": "dist/index.d.ts"

17. Publish to NPM

npm login
npm publish

Using the Component

Install the package in your project:

npm install my-awesome-button-alert-component

Import and use the component:

import { Button } from "my-awesome-button-alert-component";
import "my-awesome-button-alert-component/dist/index.css";

<Button title="Click me!" />;

Best Practices for a Production-Ready Component

  • Create a GitHub repository.
  • Add README.md and CHANGELOG.md files.
  • Include a license (e.g., MIT).
  • Use tools like Docusaurus for documentation.
  • Automate versioning with release-it.
  • Implement ESLint and Prettier for code consistency.
  • Add unit and E2E testing.
  • Set up GitHub Actions for automation.