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

@scope-analytics/node

v0.1.1

Published

Zero-code analytics for AI products — Node.js backend SDK. Wraps OpenTelemetry / Arize OpenInference and ships LLM + request telemetry to Scope.

Readme

@scope-analytics/node — Scope Node.js backend SDK

Zero-code analytics for AI products. Captures your server-side LLM calls (and ships them to Scope as universal events) by wrapping OpenTelemetry + Arize OpenInference rather than reinventing provider patching. Wire-compatible with the Python SDK (scope_analytics) — both emit the same universal event schema, so one Scope project can mix Python and Node services.

Published on npm (npm install @scope-analytics/node). Auto-captures four providers under both CommonJS and ESM: OpenAI + Anthropic (Arize OpenInference drop-ins), Google Gemini (@google/genai, a Scope-authored instrumentation — no drop-in exists), and the Vercel AI SDK (ai, zero-code — Scope auto-enables its telemetry and translates the native spans; see "Supported providers"). Also shipped: the OpenTelemetry → Scope exporter (handles chat-completions, the Responses API, and multimodal content shapes), the --import bootstrap, config + deploy/git_sha resolution, AsyncLocalStorage session/user/thread/url context, raw-by-default capture with an opt-in credential scrub (Python parity), and live call-and-capture + version-pin tests per provider, plus dual ESM+CJS builds. Coming next: framework middleware (Express/Fastify/Hono/Nest/Next route handlers), the Edge-runtime manual wrapper, an identify() helper, and per-field size caps.

Install

npm install @scope-analytics/node

Set your project secret key (from the Scope dashboard) in the environment:

export SCOPE_API_KEY="sk_live_…"   # or sk_test_…

Use it (two paths, both zero app-code for capture)

1. Zero-code bootstrap (recommended)

Start your server with the tracer pre-loaded — no code change, just a flag. The bootstrap must load before your app imports openai, which --import guarantees:

NODE_OPTIONS="--import @scope-analytics/node/register" node server.js

2. Explicit init

Call init() once at the very top of your entrypoint, before importing openai:

import { init } from '@scope-analytics/node';
init(); // reads SCOPE_API_KEY / SCOPE_ENDPOINT from the env (or pass { apiKey, endpoint })

import OpenAI from 'openai';
// …every OpenAI call from here on is captured and shipped to Scope.

Session stitching (optional, recommended)

Wrap each request so the LLM calls inside it are attributed to a user/session — this is what lets Scope stitch a user's activity across your frontend, backend, and LLM layers:

import { runWithContext } from '@scope-analytics/node';

app.use((req, res, next) => {
  runWithContext({ sessionId: req.headers['x-scope-session-id'], userId: req.user?.id }, next);
});

Without it, backend LLM calls get a temp_… session (captured, but not tied to a user).

Supported providers

Auto-captured with no app-code change: OpenAI (openai), Anthropic (@anthropic-ai/sdk), and Google Gemini (@google/genai) — plus the entire OpenAI-compatible ecosystem (Groq, Together, OpenRouter, DeepSeek, xAI, Azure OpenAI, Ollama, vLLM, …) reached through the openai SDK with a custom base_url, captured at the call site so the base URL is irrelevant.

Vercel AI SDK (ai) is also captured, zero-codegenerateText, streamText, generateObject, streamObject. The AI SDK emits telemetry only when it's enabled per call, so @scope-analytics/node enables it for you: it injects experimental_telemetry: { isEnabled: true } into those calls, deep-merged with any telemetry config you already pass (your functionId/metadata/recordInputs/… are preserved). To opt a specific call out, set experimental_telemetry: { isEnabled: false } yourself — that's respected. If you pass your own tracer in experimental_telemetry, those spans go to your tracer rather than Scope.

Module systems (CommonJS & ESM)

Auto-capture hooks your module loader, so it must be in place before your app imports its LLM SDKs — which is exactly what the --import @scope-analytics/node/register bootstrap guarantees (it also registers the ESM loader needed to instrument imports). On that bootstrap, all four providers are captured under both CommonJS and ESM. The explicit init() path covers CommonJS (where you control require order); for ESM, use the bootstrap, since imports are hoisted and a loader can't retroactively hook modules already imported.

Privacy

Raw by default (full-fidelity capture). Opt in to a best-effort credential scrub with init({ redactPatterns: CREDENTIAL_REDACT_PATTERNS }) (exported from this package) — it keeps the key and drops the value over key=value free text in prompts/responses/messages. Not a structural guarantee.

Configuration

| Option (init({…})) | Env var | Default | Notes | |---|---|---|---| | apiKey | SCOPE_API_KEY | — (required) | Project secret key (sk_live_…/sk_test_…). A public pk_… key is rejected. | | endpoint | SCOPE_ENDPOINT | https://api.scopeai.dev | Scope ingest base URL. | | environment | SCOPE_ENVIRONMENT | production | Tag on every event. | | debug | SCOPE_DEBUG | false | Verbose logging. | | serviceName | SCOPE_SERVICE_NAME | scope-app | OTel service.name. |

Deploy metadata (git_sha, deployment_id) is read once at startup from your platform's commit env var (Railway / Vercel / Render / Heroku / Cloud Run / Lambda / GIT_COMMIT_SHA) and stamped on every event — so the analyst can reason about "what changed before the drop?". Nothing is invented when no env var is present (honest non-coverage).

Design

@scope-analytics/node is a thin Scope layer over OpenTelemetry:

  • Provider instrumentations produce OpenInference GenAI spans — Arize drop-ins for OpenAI/Anthropic, a Scope-authored instrumentation for @google/genai, and the @arizeai/openinference-vercel span processor that translates the Vercel AI SDK's native spans into the same shape.
  • ScopeSpanExporter translates each LLM span into a Scope universal event and POSTs { events, source: "backend_sdk" } to ${endpoint}/api/events with Authorization: Bearer <secret>.
  • Telemetry is best-effort and never throws — a Scope outage can't crash or slow your app.

Development

npm install
npm test       # vitest (unit + a real-use pipeline → local HTTP collector)
npm run build  # tsup → dual ESM + CJS + .d.ts