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

@cruxstack/node-sdk

v1.0.7

Published

A Node.js SDK for event tracking, user traits lookup, validation, and automatic retry with queueing.

Readme

CruxStack Node SDK

A Node.js SDK for event tracking, user traits lookup, validation, and automatic retry with queueing.

Features

  • Minimal init: Only clientId at initialization
  • Per-event tenant context: Provide customerId and customerName on each event
  • Type-safe: TypeScript types + runtime validation via Zod
  • Automatic retry: Failed events are queued and retried (every 10s, up to 3 times)
  • Event enrichment: UUID, timestamp, timezone added automatically
  • Flexible payload: User-friendly keys mapped to compact API format
  • User traits: Fetch traits for one or many users

Installation

npm install @cruxstack/node-sdk

Quick Start

import { init, cruxTrack, getUserTraits, createUsers, getUsers } from '@cruxstack/node-sdk';

// Initialize SDK (clientId only)
init({
  clientId: 'your-client-id'
});

// Track an event (provide tenant context per event)
await cruxTrack('page_view', {
  userId: 'user-123',
  customerId: 'customer-456',
  customerName: 'My Company',
  eventTime: Date.now(),
  pageTitle: 'Home',
  pageUrl: 'https://app.example.com/home'
});

// Get user traits (customerId specifies which tenant to query)
const traits = await getUserTraits('user-123', 'customer-456');

// Create users for a tenant
const createResult = await createUsers({
  customer_id: 'customer-456',
  users: [
    {
      user_id: 'user-123',
      first_name: 'John',
      last_name: 'Doe',
      email: '[email protected]',
      job_title: 'Software Engineer',
      country: 'United States',
      city: 'San Francisco'
    }
  ]
});

// Get users for a tenant (paginated)
const users = await getUsers({
  customer_id: 'customer-456',
  page: 0,
  limit: 10
});

API Reference

init(config: InitConfig)

Initializes the SDK. Only clientId is required.

interface InitConfig {
  clientId: string;
}

Example:

init({ clientId: 'client-123' });

cruxTrack(categoryName: string, eventData: ExtendedEventData) | cruxTrack(events: Array<{categoryName: string, eventData: ExtendedEventData}>)

Tracks a single event or multiple events in bulk. For single events, eventData is required. For bulk events, provide an array of event objects.

interface ExtendedEventData {
  // Identity & timing
  userId?: string;
  eventTime?: number;

  // Tenant context (moved from init to event)
  customerId?: string;
  customerName?: string;

  // Session
  sessionId?: string;

  // Browser/device
  userAgent?: string;
  screenHeight?: number;
  screenWidth?: number;
  language?: string;
  platform?: string;
  adBlock?: boolean;
  viewportHeight?: number;
  viewportWidth?: number;

  // Page
  pageTitle?: string;
  pageUrl?: string;
  pagePath?: string;
  pageDomain?: string;
  pageLoadTime?: number;
  referrer?: string;

  // Network
  ipAddress?: string;

  // Custom fields
  [key: string]: any;
}

Examples:

Single Event:

await cruxTrack('purchase', {
  userId: 'user-123',
  customerId: 'customer-456',
  customerName: 'My Company',
  amount: 129.99,
  currency: 'USD'
});

Bulk Events:

const result = await cruxTrack([
  {
    categoryName: 'page_view',
    eventData: {
      userId: 'user-1',
      customerId: 'customer-1',
      customerName: 'Company A',
      pageTitle: 'Home',
      pageUrl: 'https://app.example.com/home'
    }
  },
  {
    categoryName: 'click',
    eventData: {
      userId: 'user-1',
      customerId: 'customer-1',
      customerName: 'Company A',
      button: 'signup',
      location: 'header'
    }
  },
  {
    categoryName: 'purchase',
    eventData: {
      userId: 'user-1',
      customerId: 'customer-1',
      customerName: 'Company A',
      amount: 99.99,
      currency: 'USD',
      product: 'premium-plan'
    }
  }
]);

console.log(`Bulk result: ${result.processed} processed, ${result.failed} failed`);

getUserTraits(userIds: string | string[], customerId?: string)

Fetch traits for one or more users. Pass the customerId for the tenant whose users you want to query.

type GetUserTraitsResponse = {
  success: boolean;
  data?: any;
  message?: string;
  error?: string;
}

Examples:

// Single user
const r1 = await getUserTraits('user-123', 'customer-456');

// Multiple users
const r2 = await getUserTraits(['user-123', 'user-456'], 'customer-456');

createUsers(request: CreateUsersRequest)

Creates users for a tenant. Requires tenant context (customer_id).

interface CreateUsersRequest {
  customer_id: string;
  users: UserData[];
}

interface UserData {
  user_id: string;
  first_name?: string;
  last_name?: string;
  email?: string;
  job_title?: string;
  company_name?: string;
  company_industry?: string;
  company_size?: string;
  country?: string;
  city?: string;
  state?: string;
}

Example:

await createUsers({
  customer_id: 'customer-456',
  users: [
    {
      user_id: 'user-123',
      first_name: 'John',
      last_name: 'Doe',
      email: '[email protected]',
      job_title: 'Software Engineer',
      company_name: 'Acme Corp',
      country: 'United States',
      city: 'San Francisco'
    },
    {
      user_id: 'user-456',
      first_name: 'Jane',
      last_name: 'Smith',
      email: '[email protected]',
      job_title: 'Product Manager',
      country: 'United Kingdom',
      city: 'London'
    }
  ]
});

getUsers(request: GetUsersRequest)

Retrieves users for a tenant with pagination support.

interface GetUsersRequest {
  customer_id: string;
  page?: number;    // Default: 0
  limit?: number;  // Default: 10
}

interface GetUsersResponse {
  success: boolean;
  data?: {
    users: UserData[];
    total: number;
    page: number;
    limit: number;
  };
  message?: string;
  error?: string;
}

Example:

const result = await getUsers({
  customer_id: 'customer-456',
  page: 0,
  limit: 20
});

if (result.success && result.data) {
  console.log(`Found ${result.data.total} users`);
  console.log('Users:', result.data.users);
}

Queue & Retry

  • Events are sent immediately.
  • If sending fails, events are queued and retried every 10 seconds.
  • Max retries per event: 3.

Errors

  • "SDK not initialized. Call init() first."
  • "Category name is required and must be a non-empty string"
  • "eventData is required when categoryName is a string"
  • "Events array cannot be empty"
  • "Maximum 1000 events per batch"
  • "Event tracking failed: …" (validation)
  • "Bulk event tracking failed: …" (bulk validation)
  • "Failed to send event: …" (network/API)
  • "userIds is required" / "At least one userId is required" / "All userIds must be non-empty strings"
  • "customerId is required for getUserTraits"
  • "customer_id is required" (for user management)
  • "users array cannot be empty" (for createUsers)
  • "user_id is required for each user" (for createUsers)

Headers automatically set:

  • Content-Type: application/json
  • x-client-id: {clientId}

Version Notes

  • Init now requires only clientId.
  • customerId and customerName moved from init to each event.
  • getUserTraits signature: (userIds, customerId?) – pass customerId for the tenant to query.
  • Added createUsers for user management with tenant context (customer_id).
  • Added getUsers for retrieving users with pagination support.
  • NEW: cruxTrack now supports bulk events with array input.
  • NEW: Single events require eventData parameter (no longer optional).
  • NEW: Bulk events return {success, processed, failed, errors?} response.

License

Apache-2.0