Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/vemetric/vemetric/llms.txt

Use this file to discover all available pages before exploring further.

The Vemetric Node.js SDK (@vemetric/node) enables server-side event tracking for Node.js applications, including Express, Fastify, Next.js API routes, and more.

Installation

Install the package using your preferred package manager:
npm install @vemetric/node

Setup

Initialize the Client

Create a Vemetric client instance:
import { Vemetric } from '@vemetric/node';

const vemetric = new Vemetric({
  host: 'https://hub.yourdomain.com',
  token: process.env.VEMETRIC_TOKEN
});
Store your token in environment variables and never commit it to version control.

Configuration Options

host
string
required
The URL of your Vemetric hub instanceExample: https://hub.yourdomain.com
token
string
required
Your project token from the Vemetric dashboard

Basic Usage

Track Events

Track server-side events:
await vemetric.trackEvent('UserSignup', {
  userIdentifier: user.id,
  userDisplayName: user.name,
  eventData: {
    provider: 'email',
    plan: 'free'
  }
});

Track with User Context

Include user information with every event:
await vemetric.trackEvent('ApiKeyCreated', {
  userIdentifier: ctx.user.id,
  userDisplayName: ctx.user.name,
  eventData: {
    keyName: 'Production API Key',
    permissions: ['read', 'write']
  }
});

User Identification

The Node.js SDK doesn’t have a separate identify() method. Instead, pass user information directly with events:
await vemetric.trackEvent('Signup', {
  userIdentifier: user.email,
  userDisplayName: user.name,
  userAvatarUrl: user.avatar,
  eventData: {
    provider: 'google'
  }
});

Advanced Usage

Update User Properties

Set or update user properties alongside events:
await vemetric.trackEvent('SubscriptionCreated', {
  userIdentifier: user.id,
  userData: {
    set: {
      plan: 'premium',
      subscriptionId: subscription.id,
      billingDate: subscription.currentPeriodEnd
    }
  },
  eventData: {
    planName: 'Premium',
    amount: 29.99,
    currency: 'USD'
  }
});

User Data Operations

Set or update user properties:
await vemetric.trackEvent('ProfileUpdated', {
  userIdentifier: user.id,
  userData: {
    set: {
      company: 'Acme Corp',
      role: 'admin',
      lastUpdated: new Date().toISOString()
    }
  }
});

API Reference

new Vemetric(config)

Create a new Vemetric client instance.
config
object
required

vemetric.trackEvent(name, options)

Track a server-side event.
name
string
required
Name of the event to track
options
object
Returns: Promise<void>

Framework Integration

Express.js

import express from 'express';
import { Vemetric } from '@vemetric/node';

const app = express();
const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HOST!,
  token: process.env.VEMETRIC_TOKEN!
});

app.post('/api/signup', async (req, res) => {
  const user = await createUser(req.body);
  
  await vemetric.trackEvent('UserSignup', {
    userIdentifier: user.id,
    userDisplayName: user.name,
    eventData: {
      email: user.email,
      source: req.body.source
    }
  });
  
  res.json({ success: true });
});

Next.js API Routes

import type { NextApiRequest, NextApiResponse } from 'next';
import { Vemetric } from '@vemetric/node';

const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HOST!,
  token: process.env.VEMETRIC_TOKEN!
});

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method === 'POST') {
    const { userId, action } = req.body;
    
    await vemetric.trackEvent('ApiAction', {
      userIdentifier: userId,
      eventData: { action }
    });
    
    res.status(200).json({ success: true });
  }
}

Fastify

import Fastify from 'fastify';
import { Vemetric } from '@vemetric/node';

const fastify = Fastify();
const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HOST!,
  token: process.env.VEMETRIC_TOKEN!
});

fastify.post('/api/track', async (request, reply) => {
  const { userId, event, data } = request.body;
  
  await vemetric.trackEvent(event, {
    userIdentifier: userId,
    eventData: data
  });
  
  return { success: true };
});

Hono

From the Vemetric source code:
import { Hono } from 'hono';
import { Vemetric } from '@vemetric/node';

const app = new Hono();
const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HUB_URL!,
  token: process.env.VEMETRIC_TOKEN!
});

app.post('/api/keys', async (ctx) => {
  const apiKey = await createApiKey(ctx.user);
  
  await vemetric.trackEvent('ApiKeyCreated', {
    userIdentifier: ctx.user.id,
    userDisplayName: ctx.user.name,
    eventData: {
      keyName: apiKey.name,
      permissions: apiKey.permissions
    }
  });
  
  return ctx.json({ key: apiKey });
});

Real-World Examples

SaaS Application

import { Vemetric } from '@vemetric/node';

const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HOST!,
  token: process.env.VEMETRIC_TOKEN!
});

// Track user signup
async function handleSignup(user: User) {
  await vemetric.trackEvent('Signup', {
    userIdentifier: user.id,
    userDisplayName: user.name,
    eventData: {
      provider: user.authProvider,
      plan: 'free'
    },
    userData: {
      set: {
        email: user.email,
        signupDate: new Date().toISOString()
      }
    }
  });
}

// Track project creation
async function handleProjectCreated(user: User, project: Project) {
  await vemetric.trackEvent('ProjectCreated', {
    userIdentifier: user.id,
    userDisplayName: user.name,
    eventData: {
      projectId: project.id,
      projectName: project.name,
      domain: project.domain
    },
    userData: {
      set: {
        totalProjects: user.projects.length
      }
    }
  });
}

// Track subscription changes
async function handleSubscriptionUpdate(
  user: User,
  subscription: Subscription,
  action: 'created' | 'updated' | 'cancelled'
) {
  await vemetric.trackEvent(
    action === 'created' ? 'SubscriptionCreated' :
    action === 'cancelled' ? 'SubscriptionCancelled' :
    'SubscriptionUpdated',
    {
      userIdentifier: user.id,
      userData: {
        set: {
          plan: subscription.plan,
          subscriptionStatus: subscription.status,
          billingPeriodEnd: subscription.currentPeriodEnd
        }
      },
      eventData: {
        subscriptionId: subscription.id,
        amount: subscription.amount,
        currency: subscription.currency
      }
    }
  );
}

E-commerce Backend

import { Vemetric } from '@vemetric/node';

const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HOST!,
  token: process.env.VEMETRIC_TOKEN!
});

async function trackOrder(user: User, order: Order) {
  await vemetric.trackEvent('OrderPlaced', {
    userIdentifier: user.id,
    userDisplayName: user.name,
    eventData: {
      orderId: order.id,
      total: order.total,
      itemCount: order.items.length,
      currency: order.currency,
      paymentMethod: order.paymentMethod
    },
    userData: {
      set: {
        lastOrderDate: new Date().toISOString(),
        totalOrders: user.orderCount + 1,
        lifetimeValue: user.lifetimeValue + order.total
      }
    }
  });
}

Background Jobs

import { Vemetric } from '@vemetric/node';

const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HOST!,
  token: process.env.VEMETRIC_TOKEN!
});

async function processDataExport(userId: string, format: string) {
  try {
    const exportFile = await generateExport(userId, format);
    
    await vemetric.trackEvent('DataExportCompleted', {
      userIdentifier: userId,
      eventData: {
        format,
        fileSize: exportFile.size,
        recordCount: exportFile.records
      }
    });
  } catch (error) {
    await vemetric.trackEvent('DataExportFailed', {
      userIdentifier: userId,
      eventData: {
        format,
        error: error.message
      }
    });
  }
}

Error Handling

Always wrap tracking calls in try-catch to prevent tracking errors from breaking your application:
async function createFunnel(user: User, funnel: Funnel) {
  try {
    await vemetric.trackEvent('FunnelCreated', {
      userIdentifier: user.id,
      userDisplayName: user.name,
      eventData: {
        funnelId: funnel.id,
        name: funnel.name
      }
    });
  } catch (error) {
    console.error('Failed to track funnel creation:', error);
    // Don't throw - tracking failures shouldn't break the app
  }
}

Best Practices

Initialize Vemetric once and export it:
// utils/vemetric.ts
import { Vemetric } from '@vemetric/node';

if (!process.env.VEMETRIC_TOKEN) {
  throw new Error('VEMETRIC_TOKEN is required');
}

export const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HOST!,
  token: process.env.VEMETRIC_TOKEN
});
Store credentials securely:
# .env
VEMETRIC_HOST=https://hub.yourdomain.com
VEMETRIC_TOKEN=your-project-token
Use fire-and-forget for non-critical tracking:
// Don't await if tracking isn't critical
vemetric.trackEvent('PageViewed', {
  userIdentifier: user.id
}).catch(console.error);

// Continue with response
res.json({ success: true });
Focus on events that can only be tracked server-side:
  • API key creation/revocation
  • Subscription changes
  • Admin actions
  • Background job completions
  • Payment processing

TypeScript Support

The Node.js SDK includes full TypeScript definitions:
import { Vemetric } from '@vemetric/node';

const vemetric = new Vemetric({
  host: process.env.VEMETRIC_HOST!,
  token: process.env.VEMETRIC_TOKEN!
});

// Fully typed
await vemetric.trackEvent('CustomEvent', {
  userIdentifier: string,
  userDisplayName?: string,
  eventData?: Record<string, any>,
  userData?: {
    set?: Record<string, any>;
    setOnce?: Record<string, any>;
    unset?: string[];
  }
});

Next Steps

Tracking Events

Learn event tracking best practices

React SDK

Client-side tracking with React

Configuration

Environment variables and setup

JavaScript SDK

Browser-based tracking