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

@serge-ai/js

v0.2.2

Published

Serge — agent-traffic tracker for the browser. Detect AI-agent sessions on your site, plus a custom-event API. Cookieless. SSR-safe. MIT-licensed.

Readme

@serge-ai/js

No cookies. No localStorage by default. No consent banner required. ePrivacy Art. 5(3) compliant by construction. Visitor identity derived server-side from a daily-rotating salt. Track agent traffic in EU/Swiss/UK markets without the cookie-banner tax.

The vanilla-JS core for Serge. Detects AI-agent sessions on your site (ChatGPT, Claude, Perplexity, Gemini, browser-use, …) and emits custom events from them. SSR-safe, tree-shakeable, MIT-licensed.

pnpm add @serge-ai/js
# or
npm install @serge-ai/js

For React → install @serge-ai/react instead. For Next.js → install @serge-ai/nextjs instead. For plain HTML / WordPress / Shopify (no build step) → use the script-tag snippet.

Quick start

import { init, track } from '@serge-ai/js'

init('srg_pub_xxxxxxxxxxxxxxxxxxxxxxxxxx')

document.querySelector('#checkout')?.addEventListener('click', () => {
  track('checkout_started', { plan: 'pro' })
})

Plain HTML (no build step)

<script
  defer
  data-site-id="srg_pub_xxxxxxxxxxxxxxxxxxxxxxxxxx"
  src="https://serge.ai/js/s.js"
></script>

Same API surface, exposed on window.serge('track', name, props). Pre-queue support means calls before the script loads are buffered and flushed on init.

API

init(token, options?)

Initialize the tracker. Idempotent within a page; SSR-safe (no-op when window isn't present).

init('srg_pub_xxx')
init('srg_pub_xxx', {
  apiBase: '/serge',          // first-party proxy to dodge ad-blockers (optional)
  debug: false,                // track every session, not just agents (dev only)
  requireConsent: false,       // hold tracking until consent('granted')
  defaults: '2026-05-10',      // pin SDK behavior to a published defaults date
})

The token is the public token from your Serge dashboard (srg_pub_*). It's safe to embed in client-side code, OG image URLs, and pixel src attributes. Visually distinct from the future srg_sec_* admin/management API key so a leaked token is unambiguous at a glance.

track(event, properties?)

track('add_to_cart', { sku: 'AA-batteries-10pk', price_chf: 9.9 })
  • Event name validated server-side: ^[a-z][a-z0-9_]{0,63}$ (lowercase snake_case, ≤64 chars)
  • Properties: optional, capped at ~4 KB JSON
  • No-op when not in browser, before init(), or when detection confidence is below the agent threshold (and debug=false)

consent(value)

Update consent state when init(token, { requireConsent: true }).

consent('granted')   // start tracking
consent('denied')    // stop; nothing persisted client-side
consent('unknown')   // pending; tracker stays dormant

Persisted in localStorage so the choice survives reload — and only then. Default installs (no requireConsent) don't touch storage at all.

pageview()

Manual pageview emit. The tracker auto-tracks navigation via the History API; call this only when your app uses a custom client-router that bypasses pushState/popstate.

First-party proxy (apiBase: '/serge')

Setting apiBase to a path on your own domain dodges browser ad-blockers — the snippet's network requests look like calls to your own infrastructure. Configure your edge / reverse proxy to forward /serge/* to https://serge.ai/*.

// next.config.ts
module.exports = {
  async rewrites() {
    return [{ source: '/serge/:path*', destination: 'https://serge.ai/:path*' }]
  },
}

Credentials behavior under proxy. Every regular fetch() call passes credentials: 'omit' so your site cookies are never sent — even when the request becomes same-origin via the proxy. One caveat: navigator.sendBeacon, used as a fallback on page-unload, doesn't accept a credentials option (browser API limitation). Under first-party proxy, the unload flush includes site cookies. Strip them in the proxy layer if your security team requires zero-cookie egress on every wire.

What gets sent to the server

Per session:

  • session_start: viewport, user-agent, language, agent platform classification, detection signals
  • page_view / route_change: pathname, scroll depth, time on page
  • semantic_action: your custom events (track)
  • session_end: terminal page metrics

What does not get sent:

  • Cookies (cookieless by construction)
  • IP addresses (used transiently server-side for daily-rotating bucket assignment, never stored)
  • Form input values, keystroke content, raw mouse coordinates
  • User identifiers (no vid field, no localStorage entry, no per-user identify() API)
  • Query strings (path only — sensitive query keys also stripped from referrers via the built-in scrub list)

Why no identify()?

PostHog, Mixpanel, Amplitude all ship an identify() API to link events to a user_id. Serge intentionally doesn't — Serge measures agent sessions, not end-users. The cookieless architecture exists precisely because we don't need per-user identity to do our job.

SSR safety

Every browser-API access is guarded behind typeof window !== 'undefined'. Import this package from a Next.js server component, an Edge runtime, or a Node-side test without errors. Side effects only fire after init() is called in a browser context.

Bundle size

Under 6 KB gzipped (≈5 KB Brotli). size-limit enforces this in CI.

Browser support

  • Chrome / Edge ≥ 100 (2022)
  • Firefox ≥ 100 (2022)
  • Safari ≥ 15.4 (2022)

ES2020 build target. No transpiled polyfills for older browsers.

Privacy + compliance

  • ePrivacy Art. 5(3) compliant by default — no consent banner required
  • GDPR Art. 6(1)(f) legitimate-interest legal basis for security analytics (agent detection)
  • No cookies. No localStorage by default
  • No third-party data sharing
  • Visitor identity derived server-side from a daily-rotating salt; CNIL Sheet 16 + EDPB Guidelines 2/2023 alignment

License

MIT © Superstellar LLC. See LICENSE.