Node.js Library

Our Node.js library lets you record analytics data from your node code. The requests hit our servers, and then we route your data to any analytics service you enable on your integrations page. The library is open-source, so you can check it out on Github.

All of our server-side libraries are built for high-performance, so you can use them in your web server controller code. This library uses an internal queue to make identify and track calls non-blocking and fast. It also batches messages and flushes asynchronously to our servers.

If you have any questions, run into any problems or just want to chat about our tech, feel free to email us at or submit an issue on GitHub.

Getting Started

You can install analytics-node via NPM:

npm install analytics-node

And then require it and pass it your project’s Write Key.

var analytics = require('analytics-node')('YOUR_WRITE_KEY');

The default initialization settings are production-ready and queue 20 messages before sending any requests. In development you might want to use development settings.


identify lets you tie a user to their actions and record traits about them.

You’ll want to identify a user with any relevant information as soon as they log-in or sign-up. Learn more on the Identify page.

  userId: '019mr8mf4r',
  traits: {
    email: 'Michael Bolton',
    name: '',
    plan: 'Enterprise',
    friends: 42
userId String The ID for this user in your database.
traits Object, optional A dictionary of traits you know about the user. Things like: email, name or friends.
timestamp Date, optional A Javascript date object representing when the identify took place. If the identify just happened, leave it out and we’ll use the server’s time. If you’re importing data from the past make sure you to send a timestamp.


track lets you record the actions your users perform.

You’ll want to track an event whenever the user clicks, taps or submits something in your app. Learn more on the Track page.

  userId: '019mr8mf4r',
  event: 'Purchased an Item',
  properties: {
    revenue: 39.95,
    shippingMethod: '2-day'
userId String The ID for this user in your database.
event String The name of the event you’re tracking. We recommend human-readable names like 'Played Song' or 'Updated Status'.
properties Object, optional A dictionary of properties for the event. If the event was 'Added to Cart', it might have properties like price or product.
timestamp Date, optional A Javascript date object representing when the track took place. If the track just happened, leave it out and we’ll use the server’s time. If you’re importing data from the past make sure you to send a timestamp.

Development Settings

You can use this initialization during development to make the library flush every time a message is submitted, so that you can be sure your calls are working properly.

  secret: 'YOUR_WRITE_KEY',
  flushAt: 1


alias is how you associate one identity with another. In Mixpanel it’s used to associate an anonymous user with an identified user once they sign up. For KISSmetrics and if your user switches IDs, you can use ‘alias’ to rename the ‘user_id’.

This is most frequently needed if you’re using Mixpanel. Read the method docs here.

  from: 'old_id', 
  to: 'new_id' 

Here’s a full example:

// the anonymous user does actions ...
analytics.track({ userId: 'anonymous_user', event: 'Anonymous Event' })
// the anonymous user signs up and is aliased
analytics.alias({ from: 'anonymous_user', to: '' })
// the identified user is identified
analytics.identify({ userId: '', traits: { plan: 'Free' } })
// the identified user does actions ...
analytics.track({ userId: '', event: 'Identified Action' })


You can import historical data by adding the timestamp argument to your identify and track calls. Note: If you’re tracking things that are happening right now, leave out the timestamp and our servers will timestamp the requests for you.


Our libraries are built to support high performance environments. That means it is safe to use analytics-node on a web server that’s serving hundreds of requests per second.

Every method you call does not result in an HTTP request, but is queued in memory instead. Messages are flushed in batch in the background, which allows for much faster operation.

By default, our library will flush:

  • the very first time it gets a message
  • every 20 messages (control with flushAt)
  • if 10 seconds has passed since the last flush (control with flushAfter)

How do I turn batching off?

Sometimes you might not want batching (eg. when debugging, or in short-lived programs). You can turn off batching by setting the flushAt argument to 1, and your requests will always be sent right away.

  secret: 'YOUR_WRITE_KEY',
  flushAt: 1

What happens if there are just too many messages?

If the module detects that it can’t flush faster than it’s receiving messages, it’ll simply stop accepting messages. This means your program will never crash because of a backed up analytics queue.

How do I know when this specific message is flushed?

Batching means that your message might not get sent right away. But every identify and track call returns a promise, which you can use to know when a particular message is flushed from the queue.

var promise = analytics.track({
  userId: '019mr8mf4r',
  event: 'Plays Ultimate'

promise.on('flush', function () {
  console.log("I'm 2000 miles away now!");

promise.on('error', function (err) {
  console.log('Error occured: ', err);
  // [Error: We couldnt find an app with that "secret". Have you created it at If so, please double check it.]

How do I know when any messages are flushed?

You can also get notified of any flushes or errors by listening on the analytics module itself.

analytics.on('flush', function () {
  console.log('I just got flushed. YAY!');

How do I flush right now?!

You can also flush on demand. For example, at the end of your program, you’ll want to flush to make sure there’s nothing left in the queue. Just call the flush method:

analytics.flush(function (err) {
  console.log('Flushed, and now this program can exit!');


If you hate defaults, than you’ll love how configurable the analytics-node module is. Check out these gizmos:

var analytics = require('analytics-node');
  secret: 'YOUR_WRITE_KEY',
  flushAt: 20,
  flushAfter: 10000,
  maxQueueSize: 10000,
  timerInterval: 10000,
  triggers: [analytics.triggers.size, analytics.triggers.time]
flushAt Number The number of messages to queue before flushing.
flushAfter Number The number of milliseconds to wait before automatically flushing again.
maxQueueSize Number The maximum number of messages to allow into the queue before no new message are accepted.
timerInterval Number The interval in milliseconds to check and see if there are any messages to flush.
triggers Array[Function] An array of trigger functions that determine when it’s time to flush.


You can also listen on the analytics module for the following events:

initialize After the module is initialized.
flush After the module flushes any messages from its queue.
error When a tracking or connection error occurs.

Error Handling

In order to handle errors, the analytics module will emit every time an error occurs. To avoid an uncaught exception, the library makes sure that all error events will have an event handler attached. Previous to using the 0.5.0 library, the library would emit err rather than the more conventional error.

During integration, you should listen on the error event to make sure that all your data is being properly recorded.

analytics.on('error', function (err) {
  console.warn('Error occured', err);
  // [Error: We couldnt find an app with that "secret". Have you created it at If so, please double check it.]

Multiple Clients

Different parts of your app may require different types of batching. In that case, you can initialize different instances of analytic-node:

var analytics = new require('analytics-node').Client();
analytics.init({secret: 'YOUR_WRITE_KEY', ...});

If you ever have any questions, or see anywhere we can improve our documentation, just shoot us an email at!