From Scratch to Publishing: Constructing a React Component Library on NPM

Prashant DasnurPrashant Dasnur
3 min read

A component library is a curated collection of reusable UI elementsβ€”such as buttons, inputs, and modalsβ€”that share a consistent design language and behavior.

Why it matters in 2025:

  • πŸš€ Faster Development – Stop rebuilding the same components across projects.

  • 🎯 Consistency – Maintain a unified design system across apps.

  • 🀝 Collaboration – Teams can share and maintain components in one place.

  • ♻️ Reusability – Write once, use everywhere (web, hybrid apps, even across brands).

Whether you’re a solo dev or part of a large engineering team, a well-structured React component library saves time, reduces bugs, and ensures design consistency.

Project Setup

For 2025, the recommended setup combines Vite (for speed) or create-react-library with TypeScript (for type safety).

Step 1: Create a library project

npm create vite@latest my-component-library --template react-ts
cd my-component-library

Step 2: Folder Structure

my-component-library/
 β”œβ”€β”€ src/
 β”‚   β”œβ”€β”€ components/
 β”‚   β”œβ”€β”€ index.ts
 β”‚   └── styles/
 β”œβ”€β”€ stories/
 β”œβ”€β”€ tests/
 β”œβ”€β”€ dist/
 β”œβ”€β”€ package.json
 └── tsconfig.json

Core Components

Start with simple but essential components:

Button.tsx

import React from 'react';

type ButtonProps = {
  label: string;
  onClick?: () => void;
};

export const Button = ({ label, onClick }: ButtonProps) => {
  return (
    <button onClick={onClick} className="btn-primary">
      {label}
    </button>
  );
};

βœ… Design Pattern Used: Component Composition Pattern – allows combining components and props for flexibility.

Also create:

  • Input.tsx – accessible form input with labels.

  • Modal.tsx – controlled modal with isOpen and onClose props.

Styling Options

  • CSS Modules – Scoped CSS for predictable styles.

  • Styled Components – Dynamic styling with props.

  • Tailwind-friendly – Utility-first styling for rapid iteration.

2025 Trend: Many libraries now use Tailwind + Variants for consistency and customization.

Documentation with Storybook

Storybook lets you visually test and document components.

Install:

npx storybook@latest init

Example story:

import { Button } from '../src/components/Button';

export default { title: 'Button', component: Button };

export const Primary = () => <Button label="Click Me" />;

Testing Your Components

Use Jest + React Testing Library for functional tests and Axe/Lighthouse for accessibility checks.

Example test:

import { render, screen } from '@testing-library/react';
import { Button } from '../components/Button';

test('renders button with label', () => {
  render(<Button label="Test" />);
  expect(screen.getByText(/Test/i)).toBeInTheDocument();
});

Publishing to NPM

Step 1: Update package.json

{
  "name": "my-component-library",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "peerDependencies": { "react": ">=18" }
}

Step 2: Build

npm run build

Step 3: Publish

npm login
npm publish --access public

Usage Example

import { Button } from 'my-component-library';

export default function App() {
  return <Button label="Hello World" onClick={() => alert('Clicked!')} />;
}

By building and publishing your own React component library, you’re not just writing reusable codeβ€”you’re creating a foundation for faster, cleaner, and more scalable development in every future project.

0
Subscribe to my newsletter

Read articles from Prashant Dasnur directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Prashant Dasnur
Prashant Dasnur

I’m an MCA graduate with a passion for building modern web applications.Currently exploring Laravel and React, and sharing my learning journey through blogs and projects.I enjoy solving real-world problems with clean code and creative thinking.Always learning, always building. πŸ’»πŸš€