Skip to main content

Build and Publish a Custom React + Tailwind CSS Component Library (with Webpack & Babel)

· 3 min read
Sahil Phondekar
Sr. Software Engineer @Everestek

If you’ve ever wanted to build your own reusable React component library with Tailwind CSS, but didn’t want the overhead of TypeScript or complex setups—this post is for you!

In this guide, we’ll build a simple, fully customizable component library using:

  • JavaScript
  • Tailwind CSS 3
  • Webpack + Babel
  • Ready to publish to npm

We'll even create a sample Typography component to get started.


Goal

We’re going to build a package like:

@sahilphondekar/react-tailwind-library

Ready to use in any React app with:

npm install @sahilphondekar/react-tailwind-library

Final Folder Structure

Here’s a sneak peek of what we’ll end up with:

react-tailwind-library/
├── dist/
├── src/
│ ├── components/
│ │ └── Typography/
│ │ ├── Typography.jsx
│ │ └── index.js
│ ├── index.js
│ └── styles/
│ └── tailwind.css
├── .babelrc
├── .gitignore
├── package.json
├── postcss.config.js
├── tailwind.config.js
├── webpack.config.js
└── README.md

🔧 Step 1: Initialize the Project

mkdir react-tailwind-library
cd react-tailwind-library
npm init -y

Edit your package.json:

{
"name": "@sahilphondekar/react-tailwind-library",
"main": "dist/index.js",
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
},
"scripts": {
"build": "webpack"
}
}

Step 2: Install Dependencies

Runtime Dependencies

npm install react react-dom

Dev + Build Tools

npm install -D webpack webpack-cli babel-loader \
@babel/core @babel/preset-env @babel/preset-react \
tailwindcss@3 postcss postcss-loader autoprefixer \
css-loader style-loader

Step 3: Babel Setup

Create a .babelrc file:

{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}

Step 4: Webpack Config

Create a webpack.config.js:

const path = require("path");

module.exports = {
mode: "production",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index.js",
library: "@sahilphondekar/react-tailwind-library",
libraryTarget: "umd",
clean: true,
},
externals: {
react: "react",
"react-dom": "react-dom"
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: "babel-loader"
},
{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"]
}
]
},
resolve: {
extensions: [".js", ".jsx"]
}
};

Step 5: Tailwind CSS Setup

Initialize Tailwind:

npx tailwindcss init

tailwind.config.js

module.exports = {
content: ["./src/**/*.{js,jsx}"],
theme: {
extend: {},
},
plugins: [],
};

postcss.config.js

module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

src/styles/tailwind.css

@tailwind base;
@tailwind components;
@tailwind utilities;

Step 6: Create the Typography Component

src/components/Typography/Typography.jsx

import React from "react";
import "../../styles/tailwind.css";

const Typography = ({ variant = "body", children, className = "" }) => {
const styles = {
h1: "text-4xl font-bold",
h2: "text-3xl font-semibold",
h3: "text-2xl font-semibold",
h4: "text-xl font-medium",
h5: "text-lg font-medium",
h6: "text-base font-medium",
body: "text-base",
caption: "text-sm text-gray-500",
};

const Tag = ["h1", "h2", "h3", "h4", "h5", "h6"].includes(variant)
? variant
: "p";

return <Tag className={`${styles[variant]} ${className}`}>{children}</Tag>;
};

export default Typography;

src/components/Typography/index.js

export { default } from "./Typography";

Step 7: Entry Point

src/index.js

import Typography from "./components/Typography";

export { Typography };

Step 8: Build & Publish

Build the package

npm run build

Publish to npm

npm publish --access public

Make sure you’re logged into npm with npm login and have a unique package name.


Step 9: Test it in a React App

Install the package:

npm install @sahilphondekar/react-tailwind-library

Use it:

import { Typography } from "@sahilphondekar/react-tailwind-library";

export default function App() {
return (
<div>
<Typography variant="h1">Hello UI Kit!</Typography>
</div>
);
}