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

rhinosnow

v1.0.0

Published

Detect browser extensions like ad blockers and Dark Reader

Readme

rhinoSnow

Lightweight, SSR-safe browser extension detection for JavaScript and TypeScript. Detect ad blockers and Dark Reader with zero dependencies.

Install

npm install rhinosnow

Usage

import {
  detectAdBlocker,
  detectDarkReader,
  checkAndWarnDarkReader
} from "rhinosnow";

// Detect ad blockers
if (detectAdBlocker()) {
  console.log("Ad blocker detected");
}

// Detect Dark Reader
if (detectDarkReader()) {
  console.log("Dark Reader detected");
}

// Show a dismissible warning banner if Dark Reader is active
checkAndWarnDarkReader();

// Or with a custom message
checkAndWarnDarkReader("Please disable Dark Reader for the best experience.");

API

detectAdBlocker(): boolean

Creates a hidden bait element with common ad-related class names and checks whether it was hidden or removed by an ad blocker.

Returns true if an ad blocker is detected, false otherwise.

detectDarkReader(): boolean

Checks for the presence of Dark Reader by looking for:

  • Injected <style> elements with Dark Reader classes
  • data-darkreader-* attributes on <html>
  • Dark Reader <meta> tags
  • CSS invert + hue-rotate filters on <body>

Returns true if Dark Reader is detected, false otherwise.

checkAndWarnDarkReader(warningMessage?: string): boolean

If Dark Reader is detected, displays a fixed-position warning banner in the top-right corner of the page. The banner auto-dismisses after 10 seconds or can be clicked to dismiss immediately. Repeated calls will not create duplicate banners.

| Parameter | Type | Default | |---|---|---| | warningMessage | string (optional) | "Dark Reader extension detected. Please disable it on this site to prevent potential crashes due to performance issues." |

Returns true if the warning is shown (or already visible), false otherwise.

SSR Safety

All functions are safe to import and call in server-side environments (Next.js, Nuxt, SvelteKit, etc.). They return false when window or document is not available.

Browser Support

Works in all modern browsers that support getComputedStyle and querySelector.

License

MIT