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

@luminpdf/node-ga4

v0.4.0

Published

A Node.js GA4 SDK for event tracking via Measurement Protocol API

Readme

@luminpdf/node-ga4

A Node.js Google Analytics 4 (GA4) SDK for event tracking via the Measurement Protocol API. This package provides a simple, type-safe interface for tracking events to GA4 from your server-side applications, supporting both web and app/Firebase streams.

Features

  • 🎯 Singleton Pattern: Ensures a single instance across your application
  • 🔒 Type-Safe: Full TypeScript support with proper type definitions
  • 📊 Event Tracking: Track events to GA4 via Measurement Protocol
  • 🌐 Web & App Support: Supports both web streams (measurement_id) and app/Firebase streams (firebase_app_id)
  • Validation: Built-in validation for event names, parameters, and user properties
  • 🚀 Batch Support: Track up to 25 events per request
  • 🔧 Flexible Configuration: Support for US and EU regions

Installation

npm install @luminpdf/node-ga4

or

pnpm add @luminpdf/node-ga4

or

yarn add @luminpdf/node-ga4

Prerequisites

  • Google Analytics 4 property
  • API Secret (generated in GA4 Admin > Data Streams > Measurement Protocol API secrets)
  • For web streams: Measurement ID (G-XXXXXXXXXX)
  • For app/Firebase streams: Firebase App ID
  • Node.js 18+ and TypeScript 4.5+

Usage

Initialize the Client (Web Stream)

import { GA4Client } from "@luminpdf/node-ga4";

const ga4Client = GA4Client.create({
  apiSecret: "your-api-secret",
  measurementId: "G-XXXXXXXXXX",
  region: "us",
  disableInDevelopment: false,
});

Initialize the Client (App/Firebase Stream)

const ga4Client = GA4Client.create({
  apiSecret: "your-api-secret",
  firebaseAppId: "your-firebase-app-id",
  region: "us",
  disableInDevelopment: false,
});

Track a Single Event (Web Stream)

await ga4Client.trackEvent(
  {
    eventName: "button_click",
    params: {
      button_name: "signup",
      page: "homepage",
    },
  },
  "client-id-123",
  undefined,
  "user-123"
);

Track a Single Event (App/Firebase Stream)

await ga4Client.trackEvent(
  {
    eventName: "tutorial_begin",
    params: {
      session_id: "session-123",
      engagement_time_msec: 100,
    },
  },
  undefined,
  "app-instance-id-456",
  "user-123"
);

Track Multiple Events (Batch)

await ga4Client.trackEvents({
  client_id: "client-id-123",
  user_id: "user-123",
  events: [
    {
      name: "page_view",
      params: {
        page_path: "/home",
        page_title: "Home",
      },
    },
    {
      name: "button_click",
      params: {
        button_name: "signup",
      },
    },
  ],
});

Track Events with User Properties

await ga4Client.trackEvents({
  client_id: "client-id-123",
  user_id: "user-123",
  events: [
    {
      name: "purchase",
      params: {
        transaction_id: "T12345",
        value: 99.99,
        currency: "USD",
      },
    },
  ],
  user_properties: {
    customer_tier: {
      value: "PREMIUM",
    },
    subscription_status: "active",
  },
});

Track Events with Location and Device Info

await ga4Client.trackEvents({
  client_id: "client-id-123",
  events: [
    {
      name: "page_view",
      params: {
        page_path: "/products",
      },
    },
  ],
  user_location: {
    city: "Mountain View",
    region_id: "US-CA",
    country_id: "US",
  },
  device: {
    category: "mobile",
    language: "en",
    operating_system: "iOS",
    operating_system_version: "17.0",
  },
});

Track Events with Timestamps

const timestampMicros = Date.now() * 1000;

await ga4Client.trackEvents({
  client_id: "client-id-123",
  timestamp_micros: timestampMicros,
  events: [
    {
      name: "custom_event",
      params: {
        custom_param: "value",
      },
      timestamp_micros: timestampMicros,
    },
  ],
});

Get Instance After Initialization

import { GA4Client } from "@luminpdf/node-ga4";

const ga4Client = GA4Client.getInstance();

Check Configuration

const config = ga4Client.getConfig();
console.log(config.apiSecret);
console.log(config.measurementId);
console.log(config.region);

const isConfigured = ga4Client.isClientConfigured();

API Reference

GA4Client.create(config: GA4ClientConfig): GA4Client

Creates and returns a singleton instance of the GA4Client.

Parameters:

  • config.apiSecret (required): Your GA4 API Secret
  • config.measurementId (optional): Measurement ID for web streams (G-XXXXXXXXXX)
  • config.firebaseAppId (optional): Firebase App ID for app/Firebase streams
  • config.region (optional): Region for data collection - "us" or "eu" (default: "us")
  • config.disableInDevelopment (optional): Disable tracking in development (default: false)

Note: You must provide either measurementId (for web) or firebaseAppId (for app), but not both.

GA4Client.getInstance(): GA4Client

Returns the existing singleton instance. Throws an error if create() hasn't been called.

trackEvent(options, clientId?, appInstanceId?, userId?): Promise<TrackEventsResponse>

Tracks a single event to GA4.

Parameters:

  • options.eventName (required): The name of the event (max 40 chars, alphanumeric + underscore, must start with letter)
  • options.params (optional): Event parameters (max 25 params per event)
  • options.timestamp_micros (optional): Event timestamp in microseconds
  • clientId (optional): Client ID for web streams (auto-generated if not provided)
  • appInstanceId (optional): App instance ID for app/Firebase streams (required for app streams)
  • userId (optional): User ID

trackEvents(request: TrackEventsRequest): Promise<TrackEventsResponse>

Tracks multiple events in a single batch request (max 25 events).

Parameters:

  • request.client_id (optional): Client ID for web streams (auto-generated if not provided)
  • request.app_instance_id (optional): App instance ID for app/Firebase streams (required for app streams)
  • request.user_id (optional): User ID
  • request.events (required): Array of event objects (max 25)
  • request.user_properties (optional): User properties (max 25)
  • request.user_location (optional): User location information
  • request.device (optional): Device information
  • request.timestamp_micros (optional): Request-level timestamp
  • request.validation_behavior (optional): "ENFORCE_RECOMMENDATIONS" or "RELAXED"

Validation Rules

The SDK automatically validates:

  • Event names: Max 40 characters, alphanumeric + underscore, must start with letter
  • Parameter names: Max 40 characters, alphanumeric + underscore, must start with letter
  • Parameter values: Max 100 characters (standard) or 500 characters (GA4 360)
  • User property names: Max 24 characters
  • User property values: Max 36 characters
  • Events per request: Max 25
  • Parameters per event: Max 25
  • User properties: Max 25

Limitations

According to the GA4 Measurement Protocol documentation:

  • Maximum 25 events per request
  • Maximum 25 parameters per event
  • Maximum 25 user properties
  • Event names: 40 characters or fewer
  • Parameter names: 40 characters or fewer
  • Parameter values: 100 characters or fewer (standard) or 500 characters (GA4 360)
  • User property names: 24 characters or fewer
  • User property values: 36 characters or fewer
  • Post body must be smaller than 130kB
  • Timestamps must be within the last 72 hours

Error Handling

The SDK throws errors if:

  • apiSecret is not provided
  • Neither measurementId nor firebaseAppId is provided
  • Both measurementId and firebaseAppId are provided
  • Client is used before initialization
  • Validation rules are violated
  • GA4 API calls fail

Always wrap tracking calls in try-catch blocks:

try {
  await ga4Client.trackEvent({
    eventName: "user_action",
    params: { action: "click" },
  });
} catch (error) {
  console.error("Failed to track event:", error);
}

Response Format

All tracking methods return a TrackEventsResponse object:

{
  validationMessages?: Array<{
    fieldPath: string;
    description: string;
    validationCode: string;
  }>
}

Development Mode

When disableInDevelopment is set to true, tracking methods will return early without making API calls.

Regions

  • US (default): www.google-analytics.com
  • EU: region1.google-analytics.com

Set the region option to "eu" to collect data in the European Union.

TypeScript Support

Full TypeScript support is included. Import types as needed:

import type {
  GA4ClientConfig,
  TrackEventOptions,
  TrackEventsRequest,
  TrackEventsResponse,
  EventParams,
  UserProperties,
} from "@luminpdf/node-ga4";

License

ISC