DEV Community

Mohamed Ibrahim
Mohamed Ibrahim

Posted on

Creating a Reusable Component Library with Next.js & Tailwind CSS ๐Ÿš€

Introduction

Building a reusable component library can significantly improve development efficiency, maintainability, and consistency across projects. In this guide, weโ€™ll walk through setting up a reusable component library using Next.js and Tailwind CSS, ensuring itโ€™s modular, customizable, and easy to integrate into various projects.


1. Setting Up the Project

Initialize a New Next.js Project

First, create a new Next.js project and install dependencies:

npx create-next-app@latest next-component-library --typescript
cd next-component-library
Enter fullscreen mode Exit fullscreen mode

Install Tailwind CSS

Set up Tailwind CSS by installing its dependencies:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Enter fullscreen mode Exit fullscreen mode

Configure tailwind.config.js:

module.exports = {
  content: ["./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};
Enter fullscreen mode Exit fullscreen mode

Add Tailwind to globals.css:

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

2. Structuring the Component Library

Create a Components Directory

Inside the src/ folder, create a components/ directory to organize reusable UI components.

Example: Button Component

Create a Button.tsx file inside components/:

import React from "react";
import clsx from "clsx";

type ButtonProps = {
  children: React.ReactNode;
  variant?: "primary" | "secondary" | "danger";
  onClick?: () => void;
};

const Button: React.FC<ButtonProps> = ({ children, variant = "primary", onClick }) => {
  const buttonClasses = clsx(
    "px-4 py-2 rounded-md font-semibold transition",
    {
      "bg-blue-500 text-white hover:bg-blue-600": variant === "primary",
      "bg-gray-500 text-white hover:bg-gray-600": variant === "secondary",
      "bg-red-500 text-white hover:bg-red-600": variant === "danger",
    }
  );
  return (
    <button className={buttonClasses} onClick={onClick}>
      {children}
    </button>
  );
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

3. Making Components Reusable & Customizable

Using Props for Customization

Props allow us to make components flexible. The Button component above supports different variants and actions.

Supporting Tailwind Overrides

To allow additional styles, modify the component to accept class names:

const Button: React.FC<ButtonProps & { className?: string }> = ({ children, variant = "primary", onClick, className }) => {
  return (
    <button className={clsx(buttonClasses, className)} onClick={onClick}>
      {children}
    </button>
  );
};
Enter fullscreen mode Exit fullscreen mode

4. Creating More Components

Example: Card Component

const Card: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => {
  return (
    <div className="border rounded-lg p-4 shadow-md">
      <h3 className="font-semibold text-lg mb-2">{title}</h3>
      {children}
    </div>
  );
};
export default Card;
Enter fullscreen mode Exit fullscreen mode

Example: Input Component

const Input: React.FC<{ placeholder: string; type?: string; className?: string }> = ({ placeholder, type = "text", className }) => {
  return (
    <input
      type={type}
      placeholder={placeholder}
      className={clsx("px-3 py-2 border rounded-md w-full", className)}
    />
  );
};
export default Input;
Enter fullscreen mode Exit fullscreen mode

5. Exporting Components for Easy Import

To make the library easier to use, create an index.ts inside the components/ folder:

export { default as Button } from "./Button";
export { default as Card } from "./Card";
export { default as Input } from "./Input";
Enter fullscreen mode Exit fullscreen mode

Now, importing components is simple:

import { Button, Card, Input } from "@/components";
Enter fullscreen mode Exit fullscreen mode

6. Publishing as an NPM Package (Optional)

To share your component library, you can publish it as an npm package.

Prepare the Package

  • Create a package.json in the root directory.
  • Add exports to enable modular imports.
  • Ensure your components are inside a src/ folder.

Build the Package

  1. Add a build script in package.json:
"scripts": {
  "build": "tsc && tailwindcss -o styles.css"
}
Enter fullscreen mode Exit fullscreen mode
  1. Run the build command:
npm run build
Enter fullscreen mode Exit fullscreen mode

Publish to NPM

npm login
npm publish
Enter fullscreen mode Exit fullscreen mode

Once published, it can be installed in other projects:

npm install my-nextjs-ui-library
Enter fullscreen mode Exit fullscreen mode

Conclusion

By following this guide, youโ€™ve built a reusable component library using Next.js and Tailwind CSS. This modular approach helps maintain design consistency across projects while keeping components highly customizable.

Next Steps:

  • Expand the library with more components like modals, dropdowns, and alerts.
  • Add Storybook for component documentation.
  • Implement Tailwindโ€™s @apply for reusable utility styles.
  • Optimize the package for tree shaking.

By making your components reusable and shareable, you enhance efficiency in Next.js projects while maintaining a beautiful and consistent UI. ๐Ÿš€


Follow Me

Thank you for reading my blog. ๐Ÿš€ You can follow me on GitHub and connect on Twitter

Top comments (1)

Collapse
 
razzfaxx profile image
Simeon

I'm trying to publish a NextJS v15 app with Tailwind 4, which actually does not work anymore, because they rejected the usage of tailwind.config.js. Any ideas how to handle it?