🟢 Node.js / TypeScript Integration Guide

Learn how to instrument your Node.js and TypeScript applications with TraceKit APM for zero-config distributed tracing.

Zero-Config Automatic Tracing!

TraceKit Node APM package automatically traces HTTP requests, errors, and provides first-class TypeScript support. Just install, configure, and go!

📋

Prerequisites

  • • Node.js 16.x or higher
  • • Express 4.x/5.x or NestJS 10.x
  • • An active TraceKit account
  • • A generated API key from the API Keys page

🔍 What Gets Traced Automatically?

With TraceKit Node APM installed, these operations are traced automatically:

ComponentWhat's CapturedAuto-Traced?
HTTP RequestsRoute, method, status, duration, IP✓ Yes
ExceptionsType, message, stack trace, context✓ Yes
Custom SpansManual instrumentation (optional)Manual

📦 Installation

Install the TraceKit Node APM package via npm or yarn:

npm install @tracekit/node-apm # or yarn add @tracekit/node-apm

Express Setup

JavaScript

const express = require('express');
const tracekit = require('@tracekit/node-apm');

const app = express();

// Initialize TraceKit (before routes!)
tracekit.init({
  apiKey: process.env.TRACEKIT_API_KEY,
  serviceName: 'my-express-app',
  endpoint: 'https://app.tracekit.dev/v1/traces',
});

// Add TraceKit middleware (before routes!)
app.use(tracekit.middleware());

// Your routes - automatically traced!
app.get('/api/users', (req, res) => {
  res.json({ users: ['alice', 'bob'] });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

TypeScript

import express from 'express';
import * as tracekit from '@tracekit/node-apm';

const app = express();

// Initialize TraceKit (before routes!)
tracekit.init({
  apiKey: process.env.TRACEKIT_API_KEY!,
  serviceName: 'my-express-app',
  endpoint: 'https://app.tracekit.dev/v1/traces',
});

// Add TraceKit middleware (before routes!)
app.use(tracekit.middleware());

// Your routes - automatically traced!
app.get('/api/users', (req, res) => {
  res.json({ users: ['alice', 'bob'] });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
🎉

That's It!

All HTTP requests are now automatically traced. Add the middleware before your routes and you're good to go!

🐈 NestJS Setup

1. Import TracekitModule

Add the TracekitModule to your app.module.ts:

// app.module.ts
import { Module } from '@nestjs/common';
import { TracekitModule } from '@tracekit/node-apm/nestjs';
import { UsersModule } from './users/users.module';

@Module({
  imports: [
    TracekitModule.forRoot({
      apiKey: process.env.TRACEKIT_API_KEY!,
      serviceName: 'my-nestjs-app',
      endpoint: 'https://app.tracekit.dev/v1/traces',
    }),
    UsersModule,
  ],
})
export class AppModule {}

2. Async Configuration

For environment-based configuration using ConfigModule:

// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TracekitModule } from '@tracekit/node-apm/nestjs';

@Module({
  imports: [
    ConfigModule.forRoot(),
    TracekitModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        apiKey: config.get('TRACEKIT_API_KEY')!,
        serviceName: config.get('APP_NAME', 'my-app'),
        endpoint: config.get('TRACEKIT_ENDPOINT'),
        enabled: config.get('NODE_ENV') === 'production',
      }),
    }),
  ],
})
export class AppModule {}
💡

Automatic Interceptor

The TracekitModule automatically registers a global interceptor that traces all HTTP requests. No additional middleware needed!

🔧 Manual Instrumentation (Optional)

Express - Manual Spans

import { getClient } from '@tracekit/node-apm';

app.post('/api/process', async (req, res) => {
  const client = getClient();

  const span = client.startSpan('process-data', null, {
    'user.id': req.user?.id,
    'data.size': req.body.items.length,
  });

  try {
    const result = await processData(req.body);

    client.endSpan(span, {
      'result.count': result.length,
    });

    res.json(result);
  } catch (error) {
    client.recordException(span, error as Error);
    client.endSpan(span, {}, 'ERROR');
    throw error;
  }
});

NestJS - Manual Spans

import { Injectable, Inject } from '@nestjs/common';
import { TracekitClient } from '@tracekit/node-apm/nestjs';

@Injectable()
export class DataService {
  constructor(
    @Inject('TRACEKIT_CLIENT') private tracekit: TracekitClient
  ) {}

  async processLargeDataset(data: any[]) {
    const span = this.tracekit.startSpan('process-dataset', null, {
      'dataset.size': data.length,
    });

    try {
      const results = [];
      for (const item of data) {
        const result = await this.processItem(item);
        results.push(result);
      }

      this.tracekit.endSpan(span, {
        'results.count': results.length,
      });

      return results;
    } catch (error) {
      this.tracekit.recordException(span, error as Error);
      this.tracekit.endSpan(span, {}, 'ERROR');
      throw error;
    }
  }
}

⚙️ Configuration Options

Available configuration options:

tracekit.init({
  // Required: Your TraceKit API key
  apiKey: process.env.TRACEKIT_API_KEY,

  // Optional: Service name (default: 'node-app')
  serviceName: 'my-service',

  // Optional: TraceKit endpoint
  endpoint: 'https://app.tracekit.dev/v1/traces',

  // Optional: Enable/disable tracing (default: true)
  enabled: process.env.NODE_ENV !== 'development',

  // Optional: Sample rate 0.0-1.0 (default: 1.0 = 100%)
  sampleRate: 0.5, // Trace 50% of requests
});

🔐 Environment Variables

Best practice: Store configuration in environment variables:

# .env
TRACEKIT_API_KEY=ctxio_your_generated_api_key_here
TRACEKIT_ENDPOINT=https://app.tracekit.dev/v1/traces
TRACEKIT_SERVICE_NAME=my-nodejs-app
NODE_ENV=production
⚠️

Important Security Note

Never commit your API key to version control. Use environment variables and keep your .env file out of git.

Complete Example

Here's a complete Express + TypeScript example:

import express, { Request, Response } from 'express';
import * as tracekit from '@tracekit/node-apm';

const app = express();
app.use(express.json());

// Initialize TraceKit
tracekit.init({
  apiKey: process.env.TRACEKIT_API_KEY!,
  serviceName: 'express-api',
  endpoint: 'https://app.tracekit.dev/v1/traces',
  enabled: process.env.NODE_ENV === 'production',
});

// Add middleware
app.use(tracekit.middleware());

interface User {
  id: string;
  name: string;
  email: string;
}

// Routes - automatically traced!
app.get('/api/users', (req: Request, res: Response) => {
  const users: User[] = [
    { id: '1', name: 'Alice', email: '[email protected]' },
    { id: '2', name: 'Bob', email: '[email protected]' },
  ];
  res.json(users);
});

// Manual span example
app.post('/api/users', async (req: Request, res: Response) => {
  const client = tracekit.getClient();

  const span = client.startSpan('create-user', null, {
    'user.email': req.body.email,
  });

  try {
    // Simulate user creation
    const user: User = {
      id: Date.now().toString(),
      name: req.body.name,
      email: req.body.email,
    };

    // Simulate async operation
    await new Promise(resolve => setTimeout(resolve, 100));

    client.endSpan(span, {
      'user.id': user.id,
    });

    res.status(201).json(user);
  } catch (error) {
    client.recordException(span, error as Error);
    client.endSpan(span, {}, 'ERROR');
    res.status(500).json({ error: 'Failed to create user' });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log('Server running on port ' + PORT);
});
🎉

You're all set!

Your Node.js application is now sending traces to TraceKit. Visit the Dashboard to see your traces.

🔧 Troubleshooting

Traces Not Appearing?

  1. Verify your API key is correct in environment variables
  2. Check that tracekit.init() is called before your routes
  3. Ensure middleware is added before route handlers
  4. Check Node.js console for errors
  5. Verify TraceKit endpoint is accessible

TypeScript Types Not Working?

Make sure you have TypeScript definitions installed:

npm install --save-dev @types/node # Types are included in the package, no separate @types needed!

🚀 Next Steps

  • Explore your traces on the Traces page to identify performance bottlenecks
  • Set up alert rules to get notified when issues occur
  • Add custom spans for specific operations you want to measure
  • Configure sampling rates for high-traffic applications
💡

Pro Tip

Use the getClient() function to access the TraceKit client anywhere in your application for creating custom spans!