A lightweight, promise-based confirm dialog for React, designed to be as easy to use as react-toastify, while remaining fully customizable.
npm install react-confirm-liteA lightweight, promise-based confirm dialog for React, designed to be as easy to use as react-toastify, while remaining fully customizable.






ts
confirm('Are you sure?',true)
`
then it will show the closest otherwise will show the first rendered.๐ Live Demo

๐ฆ Installation
`bash
npm install react-confirm-lite
or
yarn add react-confirm-lite
or
pnpm add react-confirm-lite
`๐ Quick Start
$3
Place
in your app (usually in root layout) and use it with confirm`tsx
import { ConfirmContainer, confirm } from 'react-confirm-lite';function App() {
async function handleAction() {
const result = await confirm('Are you sure?');
if (result) {
console.log('User confirmed!');
} else {
console.log('User cancelled!');
}
}
return (
{/ Your app content /}
);
}
`$3
By default it shows the first rendered component.
But, if you want to show a specific container by confirm api no matters where it is then you can pass the id like this
`jsx
// In confirm Api
confirm({id:'1' , message:'Are you sure?'})
// And in confirm Container
`And make sure that not to pass same id to different
In this way It will show both of these containers.One more thing that if you want to show the closest container to button to which you clicked then you can do like this.
`ts
confirm('Are you sure?', true)
`๐ฏ Features
$3
`tsx
const result = await confirm('Message here');
// Returns true for OK, false for Cancel, null for ESC/outside click
`$3
Choose from various animations:
- slide (default) - Smooth slide up/down
- fadeScale - Fade with scale effect
- bounce - Playful bounce animation
- flip - 3D flip effect
- zoom - Zoom in/out
- rotate - Rotate animation
- fadeUp / fadeDown - Directional fade
- drop - 3D drop effect
- slideRight / slideLeft - Horizontal slides
- slideVertical - Vertical slide
- slideDown - Slide down
- rotateRight - Rotate from right
- zoomSmall / bounceSmall - Subtle animations
- fadeBlur / fadeShrink - Creative effects$3
Pre-built color themes:
- dark (default) - Dark theme
- light - Light theme
- blue - Blue theme
- red - Perfect for destructive actions
- green - Success actions
- purple - Premium/feature actions$3
- closeOnEscape (default: true) - Press ESC to close
- closeOnClickOutside (default: true) - Click backdrop to close
- Returns null when closed via ESC or backdrop click$3
Control every aspect:
- Custom OK/Cancel button text
- Separate animation durations for enter/exit
- Override colors per dialog
- Custom CSS classes for all elements$3
Multiple confirm requests automatically queue and show one at a time:
`tsx
// These will show sequentially
await confirm('First?');
await confirm('Second?');
await confirm('Third?');
`$3
No CSS imports needed. Styles are automatically injected.๐จ Usage Examples
$3
`tsx
const result = await confirm('Delete this item?');
if (result) {
// User clicked OK
deleteItem();
} else if (result === false) {
// User clicked Cancel
console.log('Cancelled');
} else if (result === null) {
// User pressed ESC or clicked outside
console.log('Closed via ESC/backdrop');
}
`$3
`tsx
const result = await confirm({
title: 'Delete Account',
message: 'This will permanently delete your account and all data.',
okText: 'Delete Forever',
cancelText: 'Cancel',
colorSchema: 'red'
});
`$3
`tsx
closeOnEscape={false}
closeOnClickOutside={false}
/>
// Now dialog can only be closed with Cancel/OK buttons
`๐ง API Reference
$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
id|string| random | To show a specific container with a specific confirm() app |
| animation | AnimationType | 'slide' | Animation type (18 options) |
| animationDuration | number | 300 | Base animation duration (ms) |
| animationDurationIn | number | - | Enter animation duration |
| animationDurationOut | number | - | Exit animation duration |
| defaultColorSchema | ColorSchema | 'dark' | Default color scheme |
| closeOnEscape | boolean | true | Close with ESC key |
| closeOnClickOutside | boolean | true | Close on backdrop click |
| classes | ConfirmClasses | {} | Custom CSS classes |
$3
`tsx
// String input (simple)
await confirm('Simple message');// Object input (full options)
await confirm({
title: 'Custom Title', // Optional
message: 'Required message', // Required
okText: 'Proceed', // Optional
cancelText: 'Go Back', // Optional
colorSchema: 'blue', // Optional
});
`Return values:
-
true - User clicked OK
- false - User clicked Cancel
- null - User pressed ESC or clicked outside (if enabled)$3
`tsx
classes={{
overlay: "my-overlay-class", // Background overlay
wrapper: "my-modal-class", // Modal container
title: "my-title-class", // Title text
message: "my-message-class", // Message text
button: "my-button-class", // Both buttons
cancel: "my-cancel-class", // Cancel button only
ok: "my-ok-class", // OK button only
}}
/>
`๐ญ Custom UI with Render Prop
Want complete control over the UI? Use the render prop:
`tsx
{({
isVisible,
confirm,
handleCancel,
handleOk,
containerRef,
animationClass,
animationStyle
}) => (
modal-overlay ${isVisible ? 'show' : 'hide'}}>
{/ Your custom backdrop /}
{/ Your custom modal /}
ref={containerRef}
className={custom-modal ${animationClass}}
style={animationStyle}
>
{confirm.title}
{confirm.message}
Available render props:
-
isVisible: Boolean indicating if dialog should be visible
- confirm: The current confirm options object
- handleCancel: Function to cancel the dialog (returns false)
- handleOk: Function to confirm the dialog (returns true)
- containerRef: React ref for the modal container
- colorSchema: Current color scheme
- animationClass: CSS class for current animation
- animationStyle: Style object with animation duration
- lockScroll: Boolean, If will be true then scroll will be locked when dialog will show.๐ฑ Real-World Examples
$3
`tsx
const handleDelete = async () => {
// Force user to make explicit choice
const result = await confirm({
title: 'Delete Item',
message: 'This action cannot be undone. Are you sure?',
okText: 'Delete',
cancelText: 'Keep',
colorSchema: 'red'
}); // Result can only be true or false (no null since ESC/backdrop disabled)
if (result) {
await deleteItem();
}
};
// In your component
`$3
`tsx
// Allow closing by clicking backdrop but not ESC
const handleSubmit = async () => {
const result = await confirm({
title: 'Submit Form',
message: 'Ready to submit this form?',
okText: 'Submit',
cancelText: 'Review',
colorSchema: 'green'
});
if (result) {
await submitForm();
} else if (result === null) {
// User clicked backdrop
console.log('Closed by clicking outside');
}
};
`$3
`tsx
// Global: ESC and backdrop disabled
closeOnEscape={false}
closeOnClickOutside={false}
/>// Some dialogs can override via custom UI
const handleFlexibleDialog = async () => {
// Create custom UI that allows ESC/backdrop
const result = await confirm('Flexible dialog?');
// result can be true, false, or null
};
`๐๏ธ Container Configuration
$3
`tsx
defaultColorSchema="light" // Light theme by default
animation="zoom" // Zoom animation for all dialogs
animationDuration={400} // 400ms animations
closeOnEscape={true} // Allow ESC to close
closeOnClickOutside={true} // Allow backdrop click to close
animationDurationIn={350} // Enter: 350ms
animationDurationOut={250} // Exit: 250ms
lockScroll={false} // true by default
/>
`$3
`tsx
// Option 1: Fully closable (default)
// Users can close via: OK, Cancel, ESC, or backdrop click// Option 2: Force explicit choice
// Users can only close via: OK or Cancel buttons
// Option 3: Backdrop only
// Users can close via: OK, Cancel, or backdrop click
// Option 4: ESC only
// Users can close via: OK, Cancel, or ESC key
`
If user will close dialog box by clicking outside or by pressing escape then it will return null๐จ Animation Gallery
$3
- slide - Smooth vertical slide (default)
- slideRight / slideLeft - Horizontal slides
- slideVertical - Vertical slide
- slideDown - Slide down$3
- fadeScale - Fade with scaling
- fadeUp / fadeDown - Directional fades
- fadeBlur - Fade with blur effect
- fadeShrink - Fade with shrink effect$3
- flip - Card flip effect
- drop - 3D drop animation
- rotate / rotateRight - Rotation effects$3
- bounce / bounceSmall - Bounce effects
- zoom / zoomSmall - Zoom in/out๐จ Troubleshooting
$3
- Make sure you are on version >=1.4
- Make sure you didn't pass same id to different $3
- Make sure is mounted
- Check it's not conditionally rendered$3
- Check if closeOnEscape={true} (default)
- Ensure no other event is preventing ESC
- Try different browsers$3
- Verify closeOnClickOutside={true} (default)
- Check if any parent element is preventing clicks$3
- Verify animation name is correct
- Check browser console for errors$3
- Ensure you have @types/react installed
- Update to latest TypeScript version$3
- Use classes prop to override styles
- Check CSS specificity You can also use it in TanStack with react easily
๐ฑ Next.js Support
$3
`tsx
// app/layout.tsx
import { ConfirmContainer } from 'react-confirm-lite';export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
`$3
`tsx
// Server actions
'use server';
import { confirm } from 'react-confirm-lite';export async function serverAction() {
const result = await confirm('Confirm from server?');
if (result) {
// Perform action
} else if (result === null) {
// User pressed ESC or clicked outside
console.log('Action cancelled');
}
}
`๐ Migration from Other Libraries
$3
`tsx
// Old way (always returns true/false)
if (window.confirm('Delete?')) {
deleteItem();
}// New way (returns true/false/null)
const result = await confirm('Delete?');
if (result === true) {
await deleteItem();
} else if (result === false) {
console.log('User clicked Cancel');
} else if (result === null) {
console.log('User pressed ESC');
}
`$3
- No CSS imports needed
- Automatic queue system
- Built-in animations
- Zero configuration
- Three return states (true/false/null)Contributing to react-confirm-lite
Thanks for your interest in contributing. This project is intentionally lightweight, so the contribution workflow is kept simple and explicit. Please read this fully before starting.
---
๐ฆ Project Structure
`
react-confirm-lite/
โโ src/ # Library source code
โโ dist/ # Built output (generated)
โโ example/ # Local playground app (Vite + React)
โโ CONTRIBUTING.md
โโ README.md
โโ package.json
โโ tsup.config.ts
`* src/ โ where you make changes
* dist/ โ auto-generated by tsup (do not edit manually)
* example/ โ used to test changes locally
---
๐งฐ Prerequisites
* Node.js >= 18
* npm >= 9
* Basic familiarity with React + TypeScript
---
๐ Local Development Setup
$3
`bash
git clone https://github.com/SaadNasir-git/react-confirm-lite.git
cd react-confirm-lite
`$3
`bash
npm install
`---
๐ Development Workflow (IMPORTANT)
This project uses tsup watch mode for live rebuilding.
$3
From the project root:
`bash
npm run build:watch
`This will:
* Watch
src/ for changes
* Automatically rebuild dist/
* Re-run post-build steps when files changeโ ๏ธ Leave this terminal running.
---
$3
`bash
cd example
npm install
npm run dev
`Open the provided local URL in your browser.
---
๐งช How to Test Your Changes
1. Modify files inside
src/
2. tsup automatically rebuilds the library
3. Refresh the browser running the example app
4. Verify behavior visually and via console logsYou do not need to:
* run
npm pack
* reinstall the package
* publish to npmThis setup mirrors real-world library development.
---
๐ง What to Change (and What Not to)
$3
* Logic in
src/
* Types in types.ts
* Styles / animations
* README documentation$3
*
dist/ files manually
* Version number (maintainer handles releases)
* Build configuration unless discussed---
๐งน Code Style
* Use TypeScript types explicitly
* Avoid unnecessary abstractions
* Prefer clarity over cleverness
* Keep bundle size in mind
---
๐ Reporting Bugs
When opening an issue, include:
* What you expected
* What actually happened
* Steps to reproduce
* Browser and React version
---
๐ก Feature Requests
Feature requests are welcome, but keep in mind:
* This library aims to stay minimal
* Features should not add heavy dependencies
* API simplicity is a priority
---
๐ Development & Contributing
If you want to contribute or modify the library locally, use the built-in example app and watch mode.
$3
`bash
git clone https://github.com/SaadNasir-git/react-confirm-lite.git
cd react-confirm-lite
npm install
`$3
In the project root:
`bash
npm run build:watch
`This watches the
src/ directory and automatically rebuilds dist/ on every change.$3
In a second terminal:
`bash
cd example
npm install
npm run dev
`Open the local URL shown by Vite. Any change you make in
src/ will be reflected after a browser refresh.$3
* Do not edit files inside
dist/ manually
* You do not need to run npm pack` or reinstall the packageFor more details, see CONTRIBUTING.md.
---
By contributing, you agree that your contributions will be licensed under the MIT License.
---
Thanks for contributing to react-confirm-lite ๐
MIT License - free for personal and commercial use.
Saad Nasir - Creator of react-confirm-lite
---
โญ Found this useful? Give it a star on GitHub! โญ