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

@tracio/sdk

v0.1.3

Published

Tracio core — bot detection & device fingerprinting (vanilla JS loader)

Readme

@tracio/sdk

Tracio vanilla JS loader — typed entry point for the per-key polymorphic edge runtime.

npm version types

Install

npm install @tracio/sdk
# pnpm add @tracio/sdk
# yarn add @tracio/sdk

Framework wrappers: @tracio/react · @tracio/vue · @tracio/angular · @tracio/svelte.

Quick start

import { Tracio } from "@tracio/sdk";

const tracio = Tracio.init({ publicKey: "tracio_pk_…" });

const visitorId = await tracio.getVisitorId();
console.log("visitor:", visitorId);

const result = await tracio.getResult();
if (result.bot.detected) {
  console.warn("bot detected, confidence:", result.bot.confidence);
}

CDN / <script>

A zero-build, minified IIFE bundle is published to unpkg and jsdelivr. The global is the module namespace TracioSDK, so call TracioSDK.Tracio.init(...) (not TracioSDK.init). Pin a version — never ship a floating @latest in production:

<script src="https://cdn.jsdelivr.net/npm/@tracio/[email protected]/dist/index.min.js"></script>
<!-- or: https://unpkg.com/@tracio/[email protected]/dist/index.min.js -->
<script>
  const tracio = TracioSDK.Tracio.init({ publicKey: "tracio_pk_…" });
  tracio.getResult().then((r) => {
    if (r.bot.detected) console.warn("bot:", r.bot.confidence);
  });
</script>

window.Tracio is owned by the edge runtime the loader injects — it is not the SDK namespace. Always go through TracioSDK.

API

Tracio.init(config: TracioConfig): TracioInstance

Singleton factory. Calling it again with the same publicKey returns the existing instance. Calling it with a different key while another instance is still live throws TracioError("multiple_keys").destroy() the previous instance first.

| Field | Type | Default | Description | | ----------- | -------------- | -------------------------- | ----------------------------------------------------------------------- | | publicKey | string | — | Required. Starts with tracio_pk_. | | region | "us" \| "eu" | — | Region shorthand → edge endpoint. Ignored when endpoint is set. | | endpoint | string | 'https://edge.tracio.ai' | Base URL of the edge server. | | scriptUrl | string | — | Full override URL for <script src>. Escape hatch for SRI / self-host. | | linkedId | string | — | Stable identifier you control (user/account id). Forwarded to the edge. | | tag | string | — | Free-form label for the request (e.g. checkout, login). | | debug | boolean | false | Logs the script lifecycle and network to the console. | | timeoutMs | number | 15000 | Timeout for the full getResult() (raise if you see timeout errors). |

TracioInstance

  • getVisitorId(): Promise<string> — visitor UUID (resolves getResult() and returns its id).
  • getResult(): Promise<TracioResult> — full result with bot info; cached after the first call.
  • onReady(cb: (result) => void): void — fires once after the first successful result.
  • onError(cb: (err: TracioError) => void): void — failure channel; notifies late subscribers of an already-happened error.
  • destroy(): void — removes the <script>, releases the singleton, rejects pending promises.

TracioResult

type TracioResult = {
  visitorId: string;
  bot: { detected: boolean; confidence: number /* 0–100 */; reasons?: string[] };
};

visitorId is the canonical visitor identity. bot.detected is true when the edge verdict is bot; bot.confidence is a float in the range 0–100 (aligned with the edge RiskScore); bot.reasons lists the signal markers that drove the verdict.

TracioError

Thrown / rejected with one of the following codes. Each error exposes retryable and terminal getters; use the isTracioError / isRetryableError helpers to narrow.

| Code | retryable | When | | ---------------- | :---------: | -------------------------------------------------------------------------------- | | invalid_config | no | publicKey is missing / not a string | | multiple_keys | no | Tracio.init called with a different key while an instance is live | | non_browser | no | getResult() awaited on the server (Node) — browser-only | | load_failed | yes | <script> onerror (network / CSP / CORS) | | blocked | yes | Script loaded but window.Tracio never appeared before timeout (likely adblock) | | script_error | yes | Runtime error inside the injected edge script (reserved) | | network | yes | Transport-level fetch failure (reserved) | | timeout | yes | getResult() exceeded timeoutMs | | server | yes | window.Tracio.load().get() threw (upstream / parse failure) | | destroyed | no | A pending promise was rejected by destroy() |

terminal is the inverse of retryable for the config/usage/lifecycle codes — retrying the same call cannot help; fix the caller or re-init().

script_error and network are part of the taxonomy but not yet emitted by the current loader (script failures surface as load_failed, .get() failures as server). They are reserved for finer-grained classification and are safe to switch on today.

Error handling & adblock

import { Tracio, isTracioError, isRetryableError } from "@tracio/sdk";

try {
  const result = await Tracio.init({ publicKey: "tracio_pk_…" }).getResult();
  // …use result
} catch (err) {
  if (isRetryableError(err)) {
    // transient (blocked / load_failed / timeout / network / server) — a fresh attempt may work
    if (isTracioError(err) && err.code === "blocked") {
      // adblock / CSP blocked the edge script — fall back gracefully
    }
  } else if (isTracioError(err)) {
    // terminal (invalid_config / multiple_keys / non_browser) — fix the caller
  }
}

Adblock / CSP mitigation. When the edge script is blocked you get TracioError("blocked"). To avoid this, serve the edge from a first-party domain via endpoint (a CNAME you control, e.g. https://t.example.com) or point scriptUrl at a same-origin proxy. Make sure your CSP allows the loader and edge in script-src and connect-src.

SSR

Tracio.init on the server (Node) returns a stub instance. getResult() on the server rejects fast with a typed TracioError("non_browser") — it does not hang — so guard it out of server-render paths. All framework wrappers (@tracio/react, @tracio/vue, etc.) apply the SSR guard automatically.

Bundle size

Brotli-compressed, enforced as CI budgets:

| Artifact | Budget | | ------------------------- | ------ | | ESM (index.js) | 2.4 KB | | CJS (index.cjs) | 2.7 KB | | CDN/IIFE (index.min.js) | 2.9 KB |

Privacy & consent

Tracio performs device fingerprinting and bot detection. Depending on your jurisdiction (GDPR/ePrivacy, CCPA, …) this may require a lawful basis and/or user consent. Gate Tracio.init(...) behind your consent-management platform (CMP) and only call it once the relevant consent is granted. Disclose the processing in your privacy policy. See tracio.ai for the data-processing terms.

Example

Runnable vanilla CDN demo: ../examples/sdk.

License

MIT