npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

overlay-kit-async

v2.0.1

Published

Next-generation tools for managing overlays

Readme

overlay-kit-async · MIT License

overlay-kit-async is a fork of toss/overlay-kit that fixes overlay.openAsync behavior when an overlay is closed externally. The public API and interface are identical to the upstream — you can use it as a drop-in replacement.

Why this fork?

In upstream overlay-kit, overlay.openAsync never resolves when the overlay is closed via overlay.close(), closeAll(), unmount(), or unmountAll(). This causes memory leaks, deadlocked await calls, and broken global "close all" flows.

See toss/overlay-kit#169 for the original issue and toss/overlay-kit#215 for the unreviewed fix PR.

overlay-kit-async guarantees that openAsync always resolves:

  • With defaultValue → resolves with that value on external close. Return type is Promise<T>.
  • Without defaultValue → resolves with undefined on external close. Return type is Promise<T | undefined>.

Install

npm install overlay-kit-async

Example

First, add the provider:

import { OverlayProvider } from 'overlay-kit-async';

const app = createRoot(document.getElementById('root')!);
app.render(
  <OverlayProvider>
    <App />
  </OverlayProvider>
);

Opening Simple Overlays

import { overlay } from 'overlay-kit-async';

<Button
  onClick={() => {
    overlay.open(({ isOpen, close, unmount }) => (
      <Dialog open={isOpen} onClose={close} onExit={unmount} />
    ))
  }}
>
  Open
</Button>

Opening Asynchronous Overlays

Unlike upstream, the returned Promise always resolves — even when the overlay is closed externally.

import { overlay } from 'overlay-kit-async';

<Button
  onClick={async () => {
    const result = await overlay.openAsync<boolean>(({ isOpen, close, unmount }) => (
      <Dialog
        open={isOpen}
        onConfirm={() => close(true)}
        onClose={() => close(false)}
        onExit={unmount}
      />
    ));

    // result: boolean | undefined
    //   user confirmed  → true
    //   user dismissed  → false
    //   external close  → undefined
    if (result === undefined) {
      return;
    }
  }}
>
  Open
</Button>

For a non-nullable return type, pass a defaultValue:

const result = await overlay.openAsync<boolean>(
  ({ isOpen, close }) => (
    <Dialog open={isOpen} onConfirm={() => close(true)} onClose={() => close(false)} />
  ),
  { defaultValue: false }
);
// result: boolean — external close resolves with `false` instead of `undefined`.

Compatibility with upstream

The surface API (overlay, OverlayProvider, hooks, types) is identical to toss/overlay-kit. Migration is usually just:

- import { overlay, OverlayProvider } from 'overlay-kit';
+ import { overlay, OverlayProvider } from 'overlay-kit-async';

The one behavioral difference is openAsync:

| | Upstream | overlay-kit-async | |---|---|---| | Internal close(value) | resolves with value | resolves with value | | External close / closeAll / unmount | pending forever ❌ | resolves with defaultValue or undefined ✅ | | Return type (without defaultValue) | Promise<T> | Promise<T \| undefined> |

License

MIT © Viva Republica, Inc. (original) · forked and maintained by @p-iknow. See LICENSE for details.