@sentry/node, bugsnag, raven-js, and rollbar are libraries designed to capture, report, and analyze errors in Node.js applications. They help developers identify crashes, performance issues, and exceptions in production by sending detailed stack traces and context to a dashboard. While @sentry/node and rollbar represent the current standard SDKs for their platforms, raven-js and the root bugsnag package are legacy versions that have been replaced by newer scoped packages. Choosing the right tool depends on your need for modern features, long-term maintenance, and specific workflow integrations.
When running Node.js applications in production, knowing when and why things break is critical. @sentry/node, bugsnag, raven-js, and rollbar all aim to solve this by capturing exceptions and sending them to a central dashboard. However, they differ significantly in their current maintenance status, API design, and feature sets. Let's break down how they handle the core tasks of error tracking.
Before writing any code, you must know which packages are safe to use. Two of the four packages listed are deprecated.
@sentry/node is the current, maintained SDK for Sentry. It supports modern JavaScript features and active development.
rollbar is the current, maintained SDK for Rollbar. It is stable and receives regular updates.
bugsnag (the root package) is deprecated. The Bugsnag team now recommends @bugsnag/node for Node.js environments. Using the root package may lead to missing features or security issues.
raven-js is the legacy SDK for Sentry. It is fully deprecated and should not be used. Sentry migrated to the @sentry/* namespace years ago.
// @sentry/node: Current Standard
const Sentry = require('@sentry/node');
Sentry.init({ dsn: 'YOUR_DSN' });
// bugsnag: Deprecated Root Package (Use @bugsnag/node instead)
const bugsnag = require('bugsnag'); // ⚠️ Legacy
// Modern approach:
// const Bugsnag = require('@bugsnag/node');
// raven-js: Deprecated Legacy
const Raven = require('raven-js'); // ⚠️ Do Not Use
// rollbar: Current Standard
const Rollbar = require('rollbar');
const rollbar = new Rollbar({ accessToken: 'YOUR_TOKEN' });
Setup complexity varies slightly between providers. Modern SDKs tend to use a configuration object passed to an init function.
@sentry/node uses a straightforward init method with a DSN (Data Source Name).
// @sentry/node
const Sentry = require('@sentry/node');
Sentry.init({
dsn: 'https://publicKey@o0.ingest.sentry.io/0',
environment: 'production',
});
bugsnag (legacy) used a simple key setup, but the modern @bugsnag/node client requires a configuration object.
// bugsnag (Legacy API)
const bugsnag = require('bugsnag');
bugsnag.register('YOUR_API_KEY');
// @bugsnag/node (Modern API)
// const Bugsnag = require('@bugsnag/node');
// Bugsnag.start({ apiKey: 'YOUR_API_KEY' });
raven-js required configuring the client with a DSN before capturing.
// raven-js (Legacy)
const Raven = require('raven-js');
Raven.config('https://publicKey@sentry.io/1').install();
rollbar typically instantiates a new client object with an access token.
// rollbar
const Rollbar = require('rollbar');
const rollbar = new Rollbar({
accessToken: 'YOUR_ACCESS_TOKEN',
captureUncaught: true,
captureUnhandledRejections: true,
});
The core job of these libraries is to catch errors. All four provide methods to manually report exceptions, though the method names differ.
@sentry/node uses captureException.
// @sentry/node
try {
riskyOperation();
} catch (err) {
Sentry.captureException(err);
}
bugsnag uses notify.
// bugsnag (Legacy)
try {
riskyOperation();
} catch (err) {
bugsnag.notify(err);
}
// @bugsnag/node (Modern)
// Bugsnag.notify(err);
raven-js also used captureException, similar to the new Sentry SDK.
// raven-js (Legacy)
try {
riskyOperation();
} catch (err) {
Raven.captureException(err);
}
rollbar uses error for exceptions.
// rollbar
try {
riskyOperation();
} catch (err) {
rollbar.error(err);
}
Knowing which user encountered an error is vital for debugging. Each library allows you to attach user data to the error report.
@sentry/node uses setUser within a scope or globally.
// @sentry/node
Sentry.setUser({
id: '123',
email: 'user@example.com',
username: 'johndoe',
});
bugsnag uses user property in the notify callback or global config.
// bugsnag (Legacy)
bugsnag.notify(err, {
user: {
id: '123',
name: 'John Doe',
email: 'user@example.com'
}
});
// @bugsnag/node (Modern)
// Bugsnag.start({ user: { id: '123' } });
raven-js used setUserContext.
// raven-js (Legacy)
Raven.setContext({
user: {
id: '123',
email: 'user@example.com'
}
});
rollbar uses setPerson or passes it in the options.
// rollbar
rollbar.setPerson('123', 'johndoe', 'user@example.com');
// Or per error:
// rollbar.error(err, { person: { id: '123' } });
All four services support source maps to unminify stack traces, but the configuration differs.
@sentry/node handles source maps automatically for server-side code if configured with release flags.
// @sentry/node
Sentry.init({
dsn: 'YOUR_DSN',
release: 'my-app@1.0.0', // Required for source maps
});
bugsnag requires uploading source maps via CLI or API for full symbolication.
// bugsnag
// Requires separate CLI step:
// bugsnag-cli upload ./dist
bugsnag.register('KEY', { appVersion: '1.0.0' });
raven-js required manual upload of source maps to the Sentry server.
// raven-js (Legacy)
// Required manual CLI upload:
// sentry-cli releases files upload-sourcemaps ...
Raven.config('DSN', { release: '1.0.0' }).install();
rollbar also supports source map uploads via their CLI tool.
// rollbar
const rollbar = new Rollbar({
accessToken: 'TOKEN',
version: '1.0.0'
});
// Requires CLI: rollbar-cli upload-sourcemaps ...
Despite the differences, these libraries share common goals and patterns.
All four libraries provide mechanisms to catch unhandled promise rejections and uncaught exceptions globally.
// @sentry/node
Sentry.init({ integrations: [new Sentry.Integrations.Http()] });
// bugsnag
bugsnag.register('KEY', { notifyUnhandledRejections: true });
// raven-js (Legacy)
Raven.install(); // Auto-captures uncaught exceptions
// rollbar
const rollbar = new Rollbar({ captureUnhandledRejections: true });
Sentry and Bugsnag support "breadcrumbs" — logs that lead up to an error. Rollbar has similar telemetry features.
// @sentry/node
Sentry.addBreadcrumb({ message: 'User clicked button', category: 'ui' });
// bugsnag
bugsnag.leaveBreadcrumb('User clicked button');
// raven-js (Legacy)
Raven.captureBreadcrumb({ message: 'User clicked button' });
// rollbar
rollbar.log('User clicked button');
All services allow you to scrub sensitive data (like passwords or PII) before sending it to their servers.
// @sentry/node
Sentry.init({
beforeSend(event) {
// Scrub sensitive data
return event;
}
});
// bugsnag
bugsnag.register('KEY', {
redactedKeys: ['password', 'secret']
});
// raven-js (Legacy)
Raven.config('DSN', {
whitelistUrls: ['https://myapp.com']
});
// rollbar
const rollbar = new Rollbar({
scrubFields: ['password', 'secret']
});
| Feature | @sentry/node | bugsnag | raven-js | rollbar |
|---|---|---|---|---|
| Status | ✅ Active & Modern | ⚠️ Legacy Package | ❌ Deprecated | ✅ Active & Modern |
| Modern Alternative | N/A | @bugsnag/node | @sentry/node | N/A |
| Init Method | Sentry.init() | bugsnag.register() | Raven.config() | new Rollbar() |
| Capture Method | captureException() | notify() | captureException() | error() |
| User Context | setUser() | user object | setContext() | setPerson() |
| Ecosystem | Huge (React, Vue, etc.) | Strong (Node, Browser) | Obsolete | Solid (Node, Browser) |
@sentry/node is the clear winner for most teams today. It combines a robust free tier with deep ecosystem support and active development. If you are starting fresh, this is the default choice.
rollbar is a strong alternative if you value their specific workflow tools for error triage and assignment. It feels more like a dedicated helpdesk for errors.
bugsnag (the service) is excellent for stability monitoring, but you must use the modern @bugsnag/node package, not the root bugsnag package listed here.
raven-js should be avoided entirely. It is obsolete technology. If you find this in your codebase, plan a migration to @sentry/node immediately.
Final Thought: Error tracking is infrastructure. You want a partner that will be around for the long haul. Stick with the actively maintained SDKs (@sentry/node, @bugsnag/node, rollbar) to ensure your production visibility remains reliable.
Choose @sentry/node if you want the most widely adopted error tracking platform with deep integration into modern frameworks like Next.js, NestJS, and Express. It offers robust performance monitoring, release tracking, and a generous free tier. This is the current standard SDK for Sentry, replacing the older raven-js client.
Avoid using the root bugsnag package for new projects as it is deprecated in favor of @bugsnag/node. Choose the Bugsnag service if you prioritize stability alerts and error grouping that focuses on impact analysis. It is well-suited for teams that need clear visibility on how errors affect specific users or releases.
Do NOT use raven-js for any new development. It is the legacy JavaScript SDK for Sentry and is officially deprecated. Existing projects using raven-js should migrate to @sentry/node to ensure security patches, new features, and continued support are available.
Choose rollbar if you prefer a service with a strong focus on real-time error debugging and collaborative workflow features like assignment and resolution tracking. It provides a straightforward API and is a solid choice for teams that value a dedicated error management workflow over broad performance monitoring.
npm install @sentry/node
# Or yarn
yarn add @sentry/node
Sentry should be initialized as early in your app as possible. It is essential that you call Sentry.init before you
require any other modules in your application, otherwise auto-instrumentation of these modules will not work.
You need to create a file named instrument.js that imports and initializes Sentry:
// CJS Syntax
const Sentry = require('@sentry/node');
// ESM Syntax
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: '__DSN__',
// ...
});
You need to require or import the instrument.js file before importing any other modules in your application. This is
necessary to ensure that Sentry can automatically instrument all modules in your application:
// Import this first!
import './instrument';
// Now import other modules
import http from 'http';
// Your application code goes here
When running your application in ESM mode, you should use the Node.js
--import command line option to ensure that Sentry is loaded before
the application code is evaluated.
Adjust the Node.js call for your application to use the --import parameter and point it at instrument.js, which
contains your Sentry.init() code:
# Note: This is only available for Node v18.19.0 onwards.
node --import ./instrument.mjs app.mjs
If it is not possible for you to pass the --import flag to the Node.js binary, you can alternatively use the
NODE_OPTIONS environment variable as follows:
NODE_OPTIONS="--import ./instrument.mjs" npm run start