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

datajam

v0.3.0

Published

Local-first Stripe and product analytics SDK for Node.js

Readme

datajam

Local-first business and product analytics for Node.js — with an optional hosted cloud mode.

DataJam lets developers sync Stripe revenue data, collect first-party website/product events, store everything in local SQLite (or Postgres via DataJam Cloud), and open a built-in or hosted dashboard. It is not a required SaaS: local mode has no cloud account and does not send your data anywhere.

Backend-first package with an optional tiny browser tracker via datajam/browser.

npm version license

Why DataJam?

Stripe tells you what happened financially. Product analytics tells you what users did before that. DataJam brings those two worlds into one local database so you can answer questions like:

  • Which pages are visited most?
  • Which buttons are clicked most?
  • Where are users coming from?
  • Which landing pages or campaigns drive customers?
  • How do product events connect to Stripe revenue?

Everything runs in your own Node.js project and writes to .datajam/datajam.db.

Features

  • Stripe sync into local SQLite
  • First-party page view, click, and custom event tracking
  • Anonymous visitor and session IDs
  • Referrer and UTM source capture
  • Local dashboard for revenue and web analytics
  • CLI for init, sync, dashboard, and doctor
  • TypeScript SDK
  • Optional cloud mode via DataJam Cloud (API key + hosted portal)
  • Identity resolution with identify() in the browser SDK
  • No external analytics vendor required in local mode

Requirements

  • Node.js >=20
  • Stripe secret key for revenue sync
  • A Node.js backend if you want browser event ingestion

Install

npm install datajam

Quick Start: Stripe + Dashboard

import { DataJam } from "datajam";

const datajam = new DataJam({
  stripeSecretKey: process.env.STRIPE_SECRET_KEY
});

await datajam.init();
await datajam.sync({ full: true }); // first run

const dashboard = await datajam.dashboard();
console.log(`Dashboard running at ${dashboard.url}`);

Open:

http://127.0.0.1:3210

Later syncs can be incremental:

await datajam.sync();

Cloud Mode (optional)

Pass an API key to send Stripe sync data and tracking events to DataJam Cloud instead of local SQLite.

const datajam = new DataJam({
  stripeSecretKey: process.env.STRIPE_SECRET_KEY,
  apiKey: process.env.DATAJAM_API_KEY,
  cloudUrl: process.env.DATAJAM_CLOUD_URL ?? "https://your-datajam-host.com"
});

await datajam.init();
await datajam.sync({ full: true });

const dashboard = await datajam.dashboard();
console.log(dashboard.url); // hosted portal, e.g. https://your-host/portal

Get an API key by signing in at /portal on your DataJam Cloud deployment.

Environment variables:

DATAJAM_API_KEY=dj_live_...
DATAJAM_CLOUD_URL=https://your-datajam-host.com

First-Party Web Tracking

DataJam can collect GA-like analytics by itself. You add DataJam to your backend, then add the browser tracker to your frontend.

Backend

Mount the ingestion middleware in your Node.js app:

import express from "express";
import { DataJam } from "datajam";

const app = express();

const datajam = new DataJam({
  stripeSecretKey: process.env.STRIPE_SECRET_KEY
});

app.use("/datajam", datajam.middleware());

app.listen(3000);

The middleware accepts tracking events at:

POST /datajam/events
POST /datajam/track
POST /datajam

Frontend

Use the browser-only entrypoint:

import { initDataJam, track } from "datajam/browser";

initDataJam({
  endpoint: "/datajam/events"
});

track("signup_started", {
  plan: "premium"
});

This tracks page views automatically by default.

Identify users

After login, link anonymous visitors to a known user ID:

import { identify } from "datajam/browser";

identify(user.id, {
  email: user.email,
  name: user.name,
  plan: "pro"
});

Click Tracking

DataJam tracks marked clicks by default. This avoids collecting noisy or sensitive click data.

<button data-dj-click="checkout_cta">Start trial</button>

or:

<button data-datajam-event="pricing_cta_clicked">Start trial</button>

What Gets Stored

DataJam creates a local folder in your project:

.datajam/
  datajam.db
  config.json
  logs/
  cache/

Stripe data:

  • Customers
  • Products
  • Prices
  • Subscriptions
  • Invoices
  • Charges
  • Refunds
  • Payment Intents
  • Checkout Sessions
  • Balance Transactions
  • Disputes
  • Payouts
  • Transfers

Web analytics data:

  • Visitors
  • Sessions
  • Page views
  • Events
  • Marked clicks
  • Referrers
  • UTM source, medium, and campaign

Dashboard Metrics

Revenue analytics:

  • Revenue
  • MRR
  • ARR
  • Monthly growth
  • Refunds
  • Customers
  • Active and canceled subscriptions
  • Average order value
  • Lifetime value
  • Payment success rate
  • Revenue over time
  • Top products

Web analytics:

  • Page views
  • Visitors
  • Sessions
  • Events
  • Top pages
  • Top referrers
  • Top events and button clicks

CLI

npx datajam init
npx datajam sync
npx datajam sync --full
npx datajam dashboard
npx datajam dashboard --port 4000
npx datajam doctor

Configuration

npx datajam init creates datajam.config.ts:

export default {
  stripeSecretKey:
    process.env.STRIPE_SECRET_KEY ??
    process.env.STRIPE_SECRET_KEY_LIVE ??
    process.env.STRIPE_SECRET_KEY_TEST,
  storage: {
    engine: "sqlite"
  },
  dashboard: {
    port: 3210
  }
};

Config precedence:

  1. new DataJam({ ... })
  2. datajam.config.ts
  3. environment variables
  4. defaults

Public API

const datajam = new DataJam(options);

await datajam.init();
await datajam.sync({ full?: boolean });
await datajam.dashboard({ port?: number });
await datajam.start();
await datajam.doctor();

app.use("/datajam", datajam.middleware());
await datajam.track(event);

Browser API:

import { initDataJam, track, trackPageView } from "datajam/browser";

Where To Install It

Install datajam in your backend/server project.

Use:

import { DataJam } from "datajam";

only on the server.

Use:

import { initDataJam, track } from "datajam/browser";

only in the browser.

Do not import DataJam in frontend/client bundles because it uses Node.js APIs, SQLite, and Stripe secrets.

Next.js (App Router)

Use cloud or local mode with API route proxies so the API key stays server-side.

lib/datajam.ts:

import { DataJam } from "datajam";

export const datajam = new DataJam({
  stripeSecretKey: process.env.STRIPE_SECRET_KEY,
  apiKey: process.env.DATAJAM_API_KEY,
  cloudUrl: process.env.DATAJAM_CLOUD_URL,
  projectDir: process.cwd()
});

app/api/datajam/events/route.ts:

import { datajam } from "@/lib/datajam";

export async function POST(request: Request) {
  const body = await request.json();
  const events = Array.isArray(body.events) ? body.events : [body];
  await datajam.track(events);
  return Response.json({ ok: true, accepted: events.length }, { status: 202 });
}

components/DataJamTracker.tsx:

"use client";

import { useEffect } from "react";
import { initDataJam } from "datajam/browser";

export function DataJamTracker() {
  useEffect(() => {
    initDataJam({
      endpoint: "/api/datajam/events",
      identifyEndpoint: "/api/datajam/identify",
      trackPageViews: true,
      trackClicks: "marked-only"
    });
  }, []);

  return null;
}

Run DataJam Cloud on port 3000 and your Next.js app on another port (e.g. 3001).

Privacy Notes

DataJam is local-first and privacy-conscious by default:

  • Local mode: no DataJam cloud, no external analytics service
  • Cloud mode: data goes only to your DataJam Cloud deployment (self-hosted or your own host)
  • No form field tracking
  • No DOM/session recording
  • Click tracking is marked-only by default
  • Sensitive query params such as token, secret, password, email, code, and session are redacted in tracked URLs

You are responsible for how you disclose analytics tracking to your users.

Security Notes

  • Keep Stripe secret keys server-side only
  • Never commit .env or .datajam/
  • .datajam/datajam.db contains business and analytics data
  • The dashboard has no authentication and is intended for local/internal use

Troubleshooting

Run diagnostics:

npx datajam doctor

Common fixes:

  • Missing Stripe key: set STRIPE_SECRET_KEY
  • Empty dashboard after install: run npx datajam sync --full
  • Dashboard port in use: run npx datajam dashboard --port 4000
  • Browser tracking not appearing: confirm your backend mounted datajam.middleware() at the same endpoint used by initDataJam()

Status

DataJam is early-stage. Current paths:

  • Local mode: Stripe sync + SQLite + local dashboard
  • Cloud mode: Stripe sync + event ingestion + hosted CX portal (insights, actions, journey, reports)

The architecture is designed to grow into additional connectors and deeper revenue attribution.

License

MIT