🟢 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:
| Component | What's Captured | Auto-Traced? |
|---|---|---|
| HTTP Requests | Route, method, status, duration, IP | ✓ Yes |
| Exceptions | Type, message, stack trace, context | ✓ Yes |
| Custom Spans | Manual 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=productionImportant 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?
- Verify your API key is correct in environment variables
- Check that
tracekit.init()is called before your routes - Ensure middleware is added before route handlers
- Check Node.js console for errors
- 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!