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

@usefy/use-unmount

v0.25.1

Published

A React hook that executes a callback when the component unmounts

Readme


Overview

@usefy/use-unmount runs a callback exactly when a component unmounts. Unlike a raw useEffect cleanup, the callback always sees the latest state and props (closure freshness), errors thrown inside it are caught so they never break the rest of the unmount, and cleanup can be turned on or off with the enabled option — its value is read at unmount time.

Part of the @usefy ecosystem — a collection of production-ready React hooks designed for modern applications.

Why use-unmount?

  • Closure Freshness — The callback always sees the latest state/props at unmount time
  • Runs Only on Unmount — Toggling enabled while mounted never fires the callback; it fires only on real unmount
  • Error Handling — Errors thrown in the callback are caught and logged, never breaking the component tree unmount
  • TypeScript First — Full type safety with the exported UseUnmountOptions interface
  • SSR Compatible — Safe to render on the server (Next.js, Remix); the callback never runs during SSR
  • Zero Dependencies — Pure React implementation with only a peer dependency on React

Installation

# npm
npm install @usefy/use-unmount

# yarn
yarn add @usefy/use-unmount

# pnpm
pnpm add @usefy/use-unmount

Peer Dependencies

This package requires React 18 or 19:

{
  "peerDependencies": {
    "react": "^18.0.0 || ^19.0.0"
  }
}

Quick Start

import { useUnmount } from "@usefy/use-unmount";

function MyComponent() {
  useUnmount(() => {
    console.log("Component unmounted");
  });

  return <div>Hello</div>;
}

API Reference

useUnmount(callback, options?)

Executes callback when the component unmounts. Returns void.

Parameters

| Parameter | Type | Default | Description | | ---------- | ------------------- | ------- | -------------------------------------------- | | callback | () => void | — | Function to execute when the component unmounts | | options | UseUnmountOptions | {} | Optional configuration |

UseUnmountOptions

| Property | Type | Default | Description | | --------- | --------- | ------- | --------------------------------------------------------------- | | enabled | boolean | true | Whether to run the callback on unmount, read at unmount time |

Runs only on unmount: the enabled value is captured in a ref and read when the component actually unmounts. Flipping enabled from true to false (or back) while the component is still mounted never fires the callback.


Examples

Save the latest state on unmount

import { useState } from "react";
import { useUnmount } from "@usefy/use-unmount";

function FormComponent() {
  const [formData, setFormData] = useState({});

  useUnmount(() => {
    // formData holds the latest value at unmount time
    saveToLocalStorage(formData);
  });

  return <form>...</form>;
}

Conditional cleanup

import { useUnmount } from "@usefy/use-unmount";

function TrackingComponent({ trackingEnabled }: { trackingEnabled: boolean }) {
  useUnmount(
    () => {
      sendAnalyticsEvent("component_unmounted");
    },
    { enabled: trackingEnabled }
  );

  return <div>Tracked content</div>;
}

Resource cleanup

import { useEffect, useRef } from "react";
import { useUnmount } from "@usefy/use-unmount";

function WebSocketComponent() {
  const wsRef = useRef<WebSocket | null>(null);

  useEffect(() => {
    wsRef.current = new WebSocket("wss://example.com");
  }, []);

  useUnmount(() => {
    wsRef.current?.close();
  });

  return <div>Connected</div>;
}

TypeScript

import { useUnmount, type UseUnmountOptions } from "@usefy/use-unmount";

const options: UseUnmountOptions = { enabled: true };

useUnmount(() => {
  console.log("Goodbye");
}, options);

React StrictMode

In development with React StrictMode, components are intentionally mounted, unmounted, and remounted to detect side effects, so the unmount callback may run more than once during development. This is expected behavior and helps surface non-idempotent cleanup logic.

When to use (and when not to)

Use useUnmount to save data before removal, send exit analytics, clean up resources not managed by useEffect, or take a final state snapshot. Prefer a plain useEffect cleanup for subscriptions, event listeners, and request cancellation — the key difference is that useUnmount guarantees access to the latest values, while useEffect cleanup captures values at effect creation time.


Testing

This package maintains comprehensive test coverage to ensure reliability and stability.

Test Coverage

📊 View Detailed Coverage Report (GitHub Pages)

Test Categories

  • Callback execution on unmount
  • No callback execution on mount
  • No callback execution on rerender
  • Callback accesses latest values at unmount time
  • Updated callback reference is used on unmount
  • Latest state values are captured in callback
  • Default enabled state (true)
  • Explicit enabled: true and enabled: false
  • Callback does not fire while mounted when enabled toggles
  • Latest enabled value is honored at unmount time
  • Errors in callback are caught and logged
  • Unmount process continues despite callback errors
  • Non-Error objects thrown are handled
  • Independent instances work correctly
  • Multiple hooks in same component
  • Independent enabled states per instance
  • Rapid mount/unmount cycles
  • Undefined options handling
  • Empty options object
  • Null-ish enabled values
  • Renders on the server without throwing
  • Callback never runs during server rendering
  • Async callbacks are executed on unmount
  • Async error handling behavior

License

MIT © mirunamu

This package is part of the usefy monorepo.