Core / Node.js SDK
The base SDK for Node.js services, backend workers, CLIs, and any custom JavaScript integration.
@flash-analytics/sdk is the shared core used by all browser wrappers. Use it directly when you need server-side tracking — background jobs, payment webhooks, admin scripts, or any non-browser runtime.
Installation
Install the package
npm install @flash-analytics/sdk@2.2.3pnpm add @flash-analytics/sdk@2.2.3Set environment variables
FLASH_ANALYTICS_CLIENT_ID=00000000-0000-4000-8000-000000000000
FLASH_ANALYTICS_SECRET_KEY=your-secret-keyCreate the SDK instance
import { FlashAnalytics } from '@flash-analytics/sdk';
export const analytics = new FlashAnalytics({
appId: process.env.FLASH_ANALYTICS_CLIENT_ID!,
secretKey: process.env.FLASH_ANALYTICS_SECRET_KEY,
platform: 'node',
appVersion: process.env.npm_package_version,
deliveryStrategy: {
strategy: 'batching',
config: {
size: 25,
timeout: 5000,
fallbackToIndividual: true,
},
},
});Track events
import { analytics } from './lib/analytics';
// Identify a user (attach a profileId to future events)
await analytics.identify({ profileId: 'user_123', email: 'user@example.com' });
// Track a named event with properties
await analytics.track('invoice_paid', {
profileId: 'user_123',
invoiceId: 'inv_456',
amount: 99.00,
currency: 'USD',
});
// Flush the batch before the process exits
await analytics.flushBatch();Core APIs
track(name, props?)Send a named event
identify(payload)Set profileId and user properties
setGlobalProperties(props)Merge into every subsequent event
revenue(amount, props?)Record a charge or purchase
increment(payload)Add to a numeric user property
decrement(payload)Subtract from a numeric user property
getSession()Read session ID and expiry
fetchRemoteConfig(opts)Pull feature flag values
assignExperiment(id)Get an A/B assignment
flushBatch()Force-send queued events
Global properties
Call setGlobalProperties once at startup to tag every event with context.
analytics.setGlobalProperties({
service: 'billing-worker',
environment: process.env.NODE_ENV,
version: process.env.npm_package_version,
});Session updates
Use getSession() when you need to read the latest session synchronously. Use onSessionUpdated when another layer needs the session as soon as the SDK receives, restores, or refreshes it.
const analytics = new FlashAnalytics({
appId: process.env.FLASH_ANALYTICS_CLIENT_ID!,
secretKey: process.env.FLASH_ANALYTICS_SECRET_KEY,
onSessionUpdated(session) {
console.log(session.id);
console.log(session.estimatedExpiresAt);
console.log(session.estimatedTtlMs);
},
});
const session = analytics.getSession();
console.log(session?.id);The callback runs after successful tracking responses return session data. In browser wrappers it can also run during initialization when a valid cached session is restored.
Batching
Enable batching for high-throughput workers. Events are timestamped when they enter the queue, not when the batch is flushed, so ordering reflects real activity time. Batch responses update the same session cache used by getSession() and onSessionUpdated.
const analytics = new FlashAnalytics({
appId: process.env.FLASH_ANALYTICS_CLIENT_ID!,
deliveryStrategy: {
strategy: 'batching',
config: {
size: 25, // flush after 25 events
timeout: 5000, // or every 5 seconds
fallbackToIndividual: true, // retry individually if batch fails
},
},
});
// Always flush at process exit
process.on('beforeExit', async () => {
await analytics.flushBatch();
});Remote config
const config = await analytics.fetchRemoteConfig({
profileId: 'user_123',
userProperties: { plan: 'pro' },
country: 'US',
});
const enabled = config.getBoolean('new_checkout', false);
const title = config.getString('checkout_title', 'Checkout');
const maxItems = config.getNumber('max_cart_items', 50);
const theme = config.getJson('theme_config', {});Experiments
// Enable auto-assignment at init
const analytics = new FlashAnalytics({
appId: process.env.FLASH_ANALYTICS_CLIENT_ID!,
captureVariants: true,
});
// Cache first, API fallback
const assignment = await analytics.getExperimentById('checkout-cta');
console.log(assignment?.variantName);
// Manual assignment (always calls the API)
const variant = await analytics.assignExperiment('checkout-cta', {
profileId: 'user_123',
});Server-side tracking tip
profileId in your track calls when you know the user. Server-side events without a profileId are linked by session only, which may result in fragmented user journeys in the dashboard.