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

openconsent

v2.0.0

Published

Lightweight, dependency-free GDPR Consent Management Platform (CMP) with native Google Consent Mode v2 support. Drop-in cookie banner, script blocking, no monthly fees.

Readme

OpenConsent

A lightweight, dependency-free GDPR Consent Management Platform with native Google Consent Mode v2 support.

License: MIT npm version Size: 34 KB (9 KB gzip) Zero Dependencies Google Consent Mode v2 GDPR Compliant

The free, open-source alternative to Cookiebot, OneTrust and Iubenda: full control over your consent management, no vendor lock-in, no monthly fees. One script tag, zero dependencies, no backend required.

  • 🔒 GDPR first — no cookies before consent, 12-month expiry, URL/CSS sanitization
  • 🎯 Google Consent Mode v2 — native, denied-by-default, zero configuration
  • 🎭 Script blocking — hold tracking scripts until the user consents, hot-swap on change
  • 🧩 Works everywhere — <script> tag, npm (ESM + CommonJS), any framework
  • 🛡️ CSP friendly — nonce support
  • 🔄 SPA ready — MutationObserver for dynamically added scripts
  • 🌍 Multi-language — English and Italian included
  • 📦 TypeScript types — shipped with the package

Part of a small web-compliance toolkit: pair it with AccessiScan to audit accessibility (WCAG 2.1 / EN 301 549) on the same sites.


Install

Option A — Script tag (no build step)

<script src="https://cdn.jsdelivr.net/npm/openconsent@2/dist/openconsent.min.js"></script>
<!-- pinned to a tag on GitHub instead of npm: -->
<script src="https://cdn.jsdelivr.net/gh/iAlias/[email protected]/dist/openconsent.min.js"></script>

That's enough for the zero-config banner. Place it as the first script in <head>, immediately after <title>, so trackers are blocked before they execute.

Option B — npm

npm install openconsent
// ESM
import { createOpenConsent } from 'openconsent';

const cmp = createOpenConsent({
  config: {
    banner: {
      privacyPolicyUrl: 'https://yoursite.com/privacy-policy',
      cookiePolicyUrl: 'https://yoursite.com/cookie-policy'
    }
  }
});
// CommonJS
const { createOpenConsent } = require('openconsent');

In the browser build the singleton is exposed as window.OpenConsent (window.RSCMP is kept as a backwards-compatible alias).


Quick start

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Your Website</title>

  <!-- 1. Load OpenConsent (auto-initializes) -->
  <script src="https://cdn.jsdelivr.net/npm/openconsent@2/dist/openconsent.min.js"></script>
</head>
<body>
  <!-- 2. Category-tagged scripts stay blocked until consent is given -->
  <script type="text/plain" data-category="analytics">
    // Google Analytics (gtag.js), Plausible, Matomo, ...
  </script>

  <script type="text/plain" data-category="marketing">
    // Meta Pixel, Google Ads, TikTok Pixel, ...
  </script>
</body>
</html>

On the first visit OpenConsent shows the banner, blocks every data-category script, and wires up Google Consent Mode v2 automatically. When the user chooses, scripts in the consented categories are unblocked without a page reload.


How script blocking works

Mark any script with type="text/plain" and a data-category:

| Category | Typical use | | --- | --- | | necessary | Essential functionality — always runs | | analytics | Analytics and performance measurement | | marketing | Advertising and remarketing | | preferences | User preferences and settings |

<!-- Blocked until "analytics" is granted -->
<script type="text/plain" data-category="analytics">/* ... */</script>

<!-- Never blocked -->
<script data-category="necessary">/* ... */</script>

OpenConsent also auto-detects and blocks common trackers (Google Analytics/gtag, Meta Pixel, TikTok, Hotjar, Mixpanel, Amplitude, Clarity, DoubleClick and more), including scripts added later by SPAs. Critical attributes (type="module", nonce, integrity, crossorigin) are preserved when a script is unblocked.


Configuration

window.OpenConsent.init({
  config: {
    policyVersion: '1.0',
    banner: {
      position: 'bottom',        // 'top' | 'bottom' | 'center'
      layout: 'bar',             // 'bar' | 'box' | 'modal'
      primaryColor: '#0084ff',
      backgroundColor: '#ffffff',
      textColor: '#000000',
      buttonTextColor: '#ffffff',
      showLogo: false,
      logoUrl: 'https://yoursite.com/logo.svg',
      privacyPolicyUrl: 'https://yoursite.com/privacy-policy',
      cookiePolicyUrl: 'https://yoursite.com/cookie-policy'
    },
    categories: [
      { id: 'necessary',   name: 'Necessary',   required: true,  enabled: true },
      { id: 'analytics',   name: 'Analytics',   required: false, enabled: false },
      { id: 'marketing',   name: 'Marketing',   required: false, enabled: false },
      { id: 'preferences', name: 'Preferences', required: false, enabled: false }
    ],
    translations: {
      it: { title: 'Rispettiamo la tua privacy' /* ... */ },
      en: { title: 'We respect your privacy'    /* ... */ }
    }
  }
});

You can also configure it entirely through the script tag:

<script
  src="https://cdn.jsdelivr.net/npm/openconsent@2/dist/openconsent.min.js"
  data-site-id="YOUR_SITE_ID"
  data-api-url="https://your-api.example.com"
  data-auto-init="true"></script>

data-api-url is optional. Without it, OpenConsent runs fully client-side and never makes a network request.


API reference

The singleton is available as window.OpenConsent in the browser, or created explicitly with createOpenConsent() in a bundler.

| Method | Description | | --- | --- | | init(options?) | Initialize the CMP. Resolves when the config is loaded. | | getConsent() | Current consent categories, or null if not chosen yet. | | applyConsent(categories) | Apply categories programmatically (unblocks scripts, updates Consent Mode). | | showPreferences() | Re-open the preferences panel. | | resetConsent() | Clear consent and show the banner again. | | getStatus() | Diagnostic snapshot: { initialized, siteId, consent, blockedScripts, bannerVisible }. | | enableDebug() / disableDebug() / setDebugMode(bool) | Toggle verbose logging. | | testConsentMode() | Log the current Google Consent Mode state. |

Events

window.OpenConsent.consentManager.on('consentUpdated', (categories) => {
  console.log('Consent changed:', categories);
});

Consent categories

interface ConsentCategories {
  necessary: boolean;
  analytics: boolean;
  marketing: boolean;
  preferences: boolean;
}

Google Consent Mode v2

OpenConsent sets a denied-by-default state as early as possible and updates it when the user chooses. No configuration required. The default denies ad_storage, ad_user_data, ad_personalization, analytics_storage, functionality_storage and personalization_storage, while granting security_storage.

<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>

Framework examples

'use client';
import { useEffect } from 'react';

export default function ConsentLoader() {
  useEffect(() => {
    import('openconsent').then(({ createOpenConsent }) => {
      createOpenConsent();
    });
  }, []);

  return null;
}

Then react to changes:

window.OpenConsent.consentManager.on('consentUpdated', ({ analytics }) => {
  if (analytics) loadAnalytics();
});

See examples/gtm-implementation.html for a complete GTM walkthrough, including how to trigger tags on consent changes and inspect Consent Mode state.

Open examples/basic.html in a browser for a working demo with test buttons and a live consent-status readout.


Migrating from v1 (rs-cmp)

v2 renames the project to OpenConsent with no breaking change for existing embeds:

  • window.RSCMP still works; window.OpenConsent is the new name.
  • Consent stored under rs-cmp-consent is read and migrated automatically to openconsent (localStorage) and the cookie is renamed transparently.
  • The old CDN path dist/cmp.min.js is still published for existing script tags.
  • The old init(config) form still works; init({ siteId, apiUrl, config }) is now supported.

Optional: consent logging backend

The SDK needs no backend. If you want to store consent records, the server-side/ folder contains ready-to-adapt loggers:

  • node-logger.js — Node.js/Express + PostgreSQL example
  • php-logger.php — PHP example

These examples have their own dependencies and are not installed with the package:

cd server-side && npm install

Development

npm install     # install dev dependencies
npm run build   # build IIFE (dev + min), legacy, CommonJS and ESM bundles
npm test        # run the Jest suite
npm run lint    # ESLint

Source layout:

| File | Purpose | | --- | --- | | src/core.js | The library: all classes plus createOpenConsent(), no side effects | | src/browser.js | Browser entry: script blocking, window.OpenConsent, auto-init | | src/index.mjs | ESM entry re-exporting the core |

The committed dist/openconsent.min.js (and dist/cmp.min.js) are the published bundles; CI fails if they drift from the source.


Security & compliance

  • No cookies are set before consent.
  • Consent is stored in localStorage, with a minimal first-party presence cookie.
  • URLs and CSS color values are sanitized before being written to the DOM.
  • Optional backend logging hashes IP addresses (SHA-256) before storage.
  • Consent expires after 12 months and is re-requested.

License

MIT © Antonino Di Stefano