React Easy Modals

is a headless, zero-dependency modal stack for React. Open a modal like you call a function, and get its answer back.
Read the docs
No answer yet
const modals = useModals(); async function deleteProject() {  const answer = await modals.open(ConfirmDelete, {    project: "acme-web",  });  if (answer === "delete") removeProject();}

Get started

  1. Install. One package, no dependencies besides React.

    npm install react-easy-modals
  2. Add the provider. It renders the stack at the root of your app.

    <ModalProvider>  <App /></ModalProvider>
  3. Open a modal. Any component works. Its close value is the result.

    const ok = await modals.open(Confirm);

Features

A new modal hides the one below it until it closes.

  1. Calls show up here.
function StepModal({ close, step, onNext }) {  return (    <Modal>      <ModalContent>        <ModalTitle>Step {step}</ModalTitle>        <Button onClick={() => close()}>Back</Button>        <Button onClick={onNext}>Next step</Button>      </ModalContent>    </Modal>  );} // Each step waits underneath the next one until it closesconst openStep = (step: number) =>  modals.open(StepModal, {    step,    onNext: () => openStep(step + 1),  });
How the stack works

shadcn/ui

Add a Modal built on your Base UI Dialog, from the @alexandrejoly registry.

npx shadcn@latest add @alexandrejoly/easy-modal
settings-page.tsx
Removed: <Dialog open={open} onOpenChange={setOpen}>Removed:   <DialogContent>…</DialogContent>Removed: </Dialog>Added: const result = await modals.open(MyModal);
Read the registry guide

Docs