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

@vulcantech/analytics

v0.1.1

Published

Lightweight first-party analytics tracker for Next.js — page views, custom events, form conversions. No cookies, no fingerprinting, <1KB gzipped.

Readme

@vulcantech/analytics

Lightweight first-party analytics for VulcanTech consumer sites — page views, custom events, and form/phone/email conversion tracking. No cookies, no fingerprinting, <1KB gzipped. Events are proxied through the site's own domain to vulcantech-cms.

Also provides CMS-driven third-party tracking tags (CMSTags): GA4 / Google Ads / Meta Pixel IDs are configured in the CMS and injected server-side, so consumer sites get "codeless" tag setup with no hand-rolled gtag/fbq wiring.

Exports:

  • AnalyticsTracker — client component; tracks page views on route change.
  • trackEvent, trackFormView, trackFormSubmit, trackPhoneClick, trackEmailClick, track404, trackPageView — imperative trackers.
  • @vulcantech/analytics/route — App Router proxy handler (POST, OPTIONS) for /api/a.
  • @vulcantech/analytics/tagsCMSTags server component + fetchTrackingTags + the TrackingTags type.

Integration

Wire analytics into a consumer site (Next.js App Router):

1. Add the dependency:

npm install @vulcantech/analytics

(Inside the VulcanTech monorepo, use the workspace wiring in MONOREPO.md instead.)

2. Set the env — see Required env below.

3. Mount AnalyticsTracker in the root layout (src/app/layout.tsx) — tracks page views on every route change:

import { AnalyticsTracker } from "@vulcantech/analytics";

// <body>
//   <AnalyticsTracker />
//   {children}
// </body>

4. Re-export the proxy route src/app/api/a/route.ts — sends events to the CMS via the site's own domain (fails silently, never blocks the page):

export { POST, OPTIONS } from "@vulcantech/analytics/route";

5. Mount CMSTags in the root layout (src/app/layout.tsx) — injects the project's GA4 / Google Ads / Meta Pixel tags from the CMS. It is an async server component; render it directly in <body>:

import { CMSTags } from "@vulcantech/analytics/tags";

// <body>
//   <CMSTags />
//   <AnalyticsTracker />
//   {children}
// </body>

CMSTags fetches once per ISR window (revalidate: 60, tag tracking-tags:{projectId}) and renders null when nothing is configured. It replaces any hand-rolled <GoogleAnalytics>, Google Ads gtag Script, and Meta Pixel fbq snippets — remove those from the layout when adopting it.

Required env

VULCANTECH_PROJECT_ID, VULCANTECH_API_KEY (required) · VULCANTECH_CMS_URL (optional, defaults to https://cms.vulcantech.io).

The API key must be granted the analytics:read scope in the CMS for CMSTags to resolve tag IDs (the /api/analytics/config endpoint). Without it (or with tags disabled) the CMS returns null and only the env fallbacks apply.

Env fallbacks (tags)

When the CMS omits a field (unreachable, unconfigured, or key lacks scope), each tag ID falls back to a public env var — CMS value wins when present:

| Tag | CMS field | Env fallback | |---|---|---| | GA4 | ga4Id | NEXT_PUBLIC_GA_ID | | Google Ads | googleAdsId | NEXT_PUBLIC_GOOGLE_ADS_ID | | Meta Pixel | metaPixelId | NEXT_PUBLIC_META_PIXEL_ID |

If all three end up empty, CMSTags renders nothing.

Per-app values

None beyond env — analytics and tags are fully config-driven from the CMS.

Verifying tags are live

  • Use the CMS Integrations → Tracking Tags → Live Status panel: it fetches the deployed site and confirms each enabled tag ID is actually present in the HTML (green "Live" = the whole chain works). "Check again" re-probes.
  • In-browser, verify via the Console, not by eyeballing the Elements DOM:
    Object.keys(window.google_tag_manager)   // includes both G-… and AW-…
    window.dataLayer.filter(a => a[0] === "config")

Notes

  • The tracker skips all sends on localhost/dev hostnames; test conversions against a deployed URL.
  • CMSTags never throws — tag resolution failures are swallowed so a page build can never break on the CMS being down.
  • ISR invalidation: the CMS purges the tracking-tags:{projectId} tag when the project's analytics config changes. No consumer redeploy is needed for CMS value changes — ISR picks them up within ~60s (or instantly if the site is registered as a revalidation consumer).
  • Google Ads shares the GA4 loader. There is one gtag.js request (keyed to the GA4 ID); the Ads ID rides on it via an inline gtag('config','AW-…'). Don't expect a separate gtag/js?id=AW-… request or a standalone DOM element for it.
  • Ad blockers strip googletagmanager.com / facebook.net client-side, so tags can look absent during manual inspection — verify in a clean browser.