A beautifully crafted, open-source React UI component library. Build stunning interfaces with production-ready components, smooth animations, and comprehensive dark mode support.
- 🎨 Beautiful & Modern Components - Pre-built, production-ready UI components with elegant design
- 🌙 Dark Mode Support - Seamless light and dark mode for all components out of the box
- ✨ Smooth Animations - Powered by Framer Motion for delightful interactions
- 🎯 Tailwind CSS Integration - Utility-first styling with full Tailwind CSS support
- 📱 Fully Responsive - Mobile-first responsive design that works across all devices
- ♿ Accessible - WCAG compliant components following accessibility best practices
- ⚡ Tree-Shakeable - ES modules for optimal bundle size with modern bundlers
- 📦 Lightweight - Minimal dependencies, maximum value
npm install reline-ui
# or
yarn add reline-ui
# or
pnpm add reline-ui- React 19.2.4 or later
- React DOM 19.2.4 or later
import { Button, Accordion, AlertDialog } from "reline-ui";
export default function App() {
return (
<Button variant="primary" onClick={() => console.log("Clicked!")}>
Get Started
</Button>
);
}Reline UI works perfectly in Next.js projects:
// app/page.jsx
"use client";
import { Button, Accordion } from "reline-ui";
export default function Home() {
return (
<div className="p-8">
<Button variant="primary">Click Me</Button>
</div>
);
}Versatile button component with multiple variants for different use cases.
import { Button } from "reline-ui";
export default function ButtonDemo() {
return (
<>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="danger">Danger</Button>
<Button variant="success">Success</Button>
</>
);
}Variants: primary, secondary, outline, danger, success
Modern, frosted glass-effect button component.
import { GlassButton } from "reline-ui";
export default function GlassButtonDemo() {
return <GlassButton>Frosted Glass</GlassButton>;
}Expandable content sections with smooth animations.
import {
Accordion,
AccordionItem,
AccordionTrigger,
AccordionContent,
} from "reline-ui";
export default function AccordionDemo() {
return (
<Accordion>
<AccordionItem id="1">
<AccordionTrigger>What is Reline UI?</AccordionTrigger>
<AccordionContent>
Reline UI is a modern React component library built with Tailwind CSS
and Framer Motion.
</AccordionContent>
</AccordionItem>
<AccordionItem id="2">
<AccordionTrigger>Is it free?</AccordionTrigger>
<AccordionContent>
Yes! Reline UI is completely open-source and free to use.
</AccordionContent>
</AccordionItem>
</Accordion>
);
}Elegant accordion with glassmorphism design.
import {
GlassAccordion,
GlassAccordionItem,
GlassAccordionTrigger,
GlassAccordionContent,
} from "reline-ui";
export default function GlassAccordionDemo() {
return (
<GlassAccordion>
<GlassAccordionItem id="1">
<GlassAccordionTrigger>Feature</GlassAccordionTrigger>
<GlassAccordionContent>Content here</GlassAccordionContent>
</GlassAccordionItem>
</GlassAccordion>
);
}Customizable modal dialogs for alerts and confirmations.
import {
AlertDialog,
AlertDialogTrigger,
AlertDialogContent,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogAction,
AlertDialogCancel,
} from "reline-ui";
export default function AlertDialogDemo() {
return (
<AlertDialog>
<AlertDialogTrigger>Open Dialog</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Confirm</AlertDialogTitle>
<AlertDialogDescription>
Are you absolutely sure?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction>Confirm</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}Informational callout box component.
import { Callout } from "reline-ui";
export default function CalloutDemo() {
return <Callout>Important information here</Callout>;
}Organized content in tabbed interface.
import { TabList, Tab, TabPanel, TabContext } from "reline-ui";
export default function TabsDemo() {
return (
<TabContext>
<TabList>
<Tab value="tab1">Tab 1</Tab>
<Tab value="tab2">Tab 2</Tab>
</TabList>
<TabPanel value="tab1">Content 1</TabPanel>
<TabPanel value="tab2">Content 2</TabPanel>
</TabContext>
);
}Responsive card component with media support.
import { MediaCard } from "reline-ui";
export default function MediaCardDemo() {
return (
<MediaCard
mediaSrc="https://example.com/image.jpg"
mediaType="image"
title="Amazing Project"
subtitle="Powered by Reline UI"
href="https://example.com"
/>
);
}Built-in dark mode support with theme context.
import { RelineThemeProvider, ThemeSwitcher, ThemeToggle } from "reline-ui";
export default function App() {
return (
<RelineThemeProvider>
<ThemeSwitcher theme="light" setTheme={() => {}} />
<ThemeToggle />
<YourApp />
</RelineThemeProvider>
);
}All components are built with Tailwind CSS and accept a className prop for custom styling:
<Button className="custom-class">Custom Styled Button</Button>Dark mode is automatically supported. Just configure Tailwind CSS with the dark class strategy:
// tailwind.config.js
export default {
darkMode: "class",
// ...
};For detailed component documentation, prop references, and advanced usage examples, visit the GitHub repository.
# Clone the repository
git clone https://github.com/Reline-UI/reline-ui.git
cd reline-ui
# Install dependencies
npm install
# Start development server
npm run dev
# Run tests
npm run test
# Build for production
npm run buildWe welcome contributions! Please follow these guidelines when contributing new components or features to Reline UI.
-
Fork the repository
git clone https://github.com/YourUsername/reline-ui.git cd reline-ui -
Create a feature branch
git checkout -b feature/component-name
-
Install dependencies
npm install
-
Start development server
npm run dev
Each component must follow this folder structure:
src/components/
├── ComponentName/
│ ├── index.jsx # Main component file
│ ├── docs.md # Documentation (optional but recommended)
│ └── ComponentName.jsx # (optional) For complex components with multiple files
Step 1: Create the component folder
mkdir -p src/components/MyNewComponentStep 2: Create the component file (index.jsx)
Use named exports (NOT default exports):
// src/components/MyNewComponent/index.jsx
"use client";
import { motion } from "framer-motion";
import { cn } from "../../utils/cn.js";
// Export named components
export function MyNewComponent({
variant = "primary",
children,
className,
...props
}) {
const baseStyles = "px-4 py-2 rounded-lg transition-colors duration-200";
const variants = {
primary:
"bg-[#18181B] text-[#FAFAFA] hover:bg-[#18181B]/90 dark:bg-[#FAFAFA] dark:text-[#18181B]",
secondary:
"bg-[#F4F4F5] text-[#18181B] hover:bg-[#E4E4E7] dark:bg-[#27272A]",
};
return (
<motion.div
className={cn(baseStyles, variants[variant], className)}
{...props}
>
{children}
</motion.div>
);
}
// Export additional components if needed
export function MyNewComponentItem({ children }) {
return <div className="component-item">{children}</div>;
}Step 3: Update src/index.js to export your component
Add your named exports to src/index.js:
// In src/index.js, add:
export {
MyNewComponent,
MyNewComponentItem,
} from "./components/MyNewComponent/index.jsx";**Step 4: Create documentation **
Create a docs.md file describing usage:
# MyNewComponent
Brief description of what the component does.
## Usage
\`\`\`jsx
import { MyNewComponent } from "reline-ui";
export default function Demo() {
return <MyNewComponent variant="primary">Click Me</MyNewComponent>;
}
\`\`\`
## Props
| Prop | Type | Default | Description |
| --------- | --------- | --------- | ---------------------- |
| variant | string | "primary" | Visual style variant |
| children | ReactNode | - | Component content |
| className | string | - | Additional CSS classes |The cn utility is located at src/utils/cn.js and merges Tailwind classes intelligently:
// src/utils/cn.js
import { twMerge } from "tailwind-merge";
import clsx from "clsx";
export function cn(...inputs) {
return twMerge(clsx(inputs));
}Why use cn?
- Merges classes - Combines multiple Tailwind classes
- Handles conflicts -
twMergeintelligently resolves conflicting Tailwind utilities - Supports conditionals - Works with clsx for conditional classes
- Prevents duplication - Ensures consistent styling
import { cn } from "../../utils/cn.js";
export function MyComponent({ variant, isActive, className }) {
return (
<div
className={cn(
// Base styles
"px-4 py-2 rounded-lg transition-all",
// Variant styles
variant === "primary" && "bg-blue-500 text-white",
variant === "secondary" && "bg-gray-200 text-black",
// Conditional styles
isActive && "ring-2 ring-blue-600",
// User-provided classes (highest priority)
className,
)}
>
Content
</div>
);
}The Tailwind config is in tailwind.config.js:
export default {
content: [
"./index.html",
"./src/**/*.{js,jsx}", // Scans all component files
"./example/**/*.{js,jsx}", // Includes example files
],
theme: {
extend: {
animation: {
"spin-slow": "spin 6s linear infinite",
// Add custom animations here
},
},
},
darkMode: "class", // Enables dark mode with class strategy
};Dark Mode Support:
Use the dark: prefix for dark mode styles:
className={cn(
"text-black bg-white", // Light mode
"dark:text-white dark:bg-black", // Dark mode
)}The src/utils/ folder contains utility functions and helpers:
src/utils/
├── cn.js # Class name merger utility
└── [other-utils] # Add more utilities here as needed
Creating new utilities:
// src/utils/myHelper.js
export function myHelper(param) {
// Your utility logic
return result;
}
// In your component, import and use:
import { myHelper } from "../../utils/myHelper.js";// ✅ Correct
export function Button({ children }) { ... }
export function ButtonGroup({ children }) { ... }
// ❌ Avoid
export default function Button({ children }) { ... }import { cn } from "../../utils/cn.js";
// Use it to merge styles
className={cn(baseStyles, variants[variant], className)}className={cn(
"bg-white dark:bg-[#09090B]",
"text-black dark:text-white"
)}import { motion, AnimatePresence } from "framer-motion";
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
Animated content
</motion.div>;export function MyComponent({ children, className, ...props }) {
return (
<div className={cn("base-styles", className)} {...props}>
{children}
</div>
);
}"use client"; // Required for Next.js App Router
import React from "react";
// ...Before submitting a PR:
- Component uses named exports (no defaults)
- Component uses
cnutility for class merging - Component supports dark mode styles
- Component is exported in src/index.js
- Folder structure matches convention:
src/components/ComponentName/index.jsx -
classNameprop is accepted for customization - Documentation added (docs.md file)
- Code follows existing style patterns
- Component is responsive and mobile-friendly
- All props are properly typed/documented
-
Commit your changes
git commit -m "Add MyNewComponent with dark mode support" -
Push to your fork
git push origin feature/component-name
-
Open a Pull Request
- Provide a clear description of the component
- Include usage examples
- Link any related issues
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by the Reline UI team