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

react-usefavicon

v2.0.0

Published

useFavicon: a React Hook to dynamically modify the favicon

Downloads

417

Readme

react-usefavicon

npm version

Check a live demo here

react-usefavicon is a React hook to dynamically draw on your favicon. Composite badges, text bubbles, progress indicators, or anything you can draw on a canvas onto your existing favicon. This is useful to notify the user of changes or progress, especially if these are long running and the user is expected to switch tabs. GitHub (read more), Slack, and many more websites use this technique.

Works with modern React frameworks: Next.js (App Router & Pages Router), React Router, TanStack Router, Remix, and more. Fully SSR-safe!

React 19 note: If you just need to set a static favicon URL, React 19 supports rendering <link rel="icon" href={href} /> directly in your components — React will hoist it to <head> for you. This hook is most valuable when you need to draw on the favicon using canvas (badges, overlays, dynamic text).

Installing

If you use npm

npm install react-usefavicon

For yarn

yarn add react-usefavicon

Usage

import { useFavicon, emojiSvg } from "react-usefavicon";

const { drawOnFavicon, restoreFavicon, setFaviconHref, svgToFavicon } = useFavicon();

Returns an object of stable handler functions.

Draw on the favicon

Draw anything on top of the current favicon using the Canvas API. The current favicon is drawn as the background first, then your callback runs on top.

import { useFavicon, drawCircle, drawTextBubble } from "react-usefavicon";

function Notifications({ count }) {
  const { drawOnFavicon, restoreFavicon } = useFavicon();

  useEffect(() => {
    if (count > 0) {
      drawOnFavicon(drawCircle, { fillColor: "red", radius: 40, x: 200, y: 200 });
    } else {
      restoreFavicon();
    }
  }, [count, drawOnFavicon, restoreFavicon]);

  return <span>{count} notifications</span>;
}

Or write your own draw callback. It receives the canvas context, the favicon size, and any extra options you pass:

drawOnFavicon((ctx, size) => {
  ctx.fillStyle = "green";
  ctx.beginPath();
  ctx.arc(size - 30, size - 30, 25, 0, Math.PI * 2);
  ctx.fill();
});

Options

| Option | Type | Default | Description | |---|---|---|---| | faviconSize | number | 256 | Canvas size in px | | clear | boolean | false | Start with a blank canvas instead of drawing over the current favicon | | ...rest | any | — | Passed through as the third argument to your draw callback |

If you call drawOnFavicon multiple times, drawings stack. Call restoreFavicon() first to draw on the clean original.

Built-in draw functions

Three draw helpers are included for common patterns:

import { drawCircle, drawTextBubble, drawSquare } from "react-usefavicon";

drawCircle — draws a filled circle (notification dot)

drawOnFavicon(drawCircle, { fillColor: "red", radius: 40, x: 200, y: 200 });

drawTextBubble — draws a rounded badge with a text label (unread count)

drawOnFavicon(drawTextBubble, { label: "3", color: "orangered", fontSize: 128, font: "sans-serif" });

drawSquare — draws a filled square

drawOnFavicon(drawSquare, { fillColor: "black", length: 50, x: 200, y: 200 });

All options have sensible defaults — you can call drawOnFavicon(drawCircle) with no options for a red dot in the bottom-right corner.

Set an emoji favicon

emojiSvg is a standalone helper — works with the hook or with React 19's <link>:

setFaviconHref(`data:image/svg+xml,${emojiSvg("🔥")}`);

// or without the hook:
<link rel="icon" href={`data:image/svg+xml,${emojiSvg("🔥")}`} />

Set a favicon URL

setFaviconHref("/favicons/active.png");

Render JSX SVG as favicon

await svgToFavicon(
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <circle cx="50" cy="50" r="50" fill="tomato" />
  </svg>
);

This dynamically imports react-dom/server to render the SVG to a string. Only <svg> elements are accepted.

Restore the original favicon

restoreFavicon();

Resets the favicon to whatever it was when the hook first mounted.

SSR

The hook is SSR-safe — it no-ops on the server and updates the favicon after hydration. In Next.js App Router, mark the component with 'use client'.

Credits & Inspiration

Ideas