datajam
v0.3.0
Published
Local-first Stripe and product analytics SDK for Node.js
Maintainers
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.
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 datajamQuick 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:3210Later 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/portalGet 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.comFirst-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 /datajamFrontend
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 doctorConfiguration
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:
new DataJam({ ... })datajam.config.ts- environment variables
- 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, andsessionare 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
.envor.datajam/ .datajam/datajam.dbcontains business and analytics data- The dashboard has no authentication and is intended for local/internal use
Troubleshooting
Run diagnostics:
npx datajam doctorCommon 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 byinitDataJam()
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
