bugsnag, newrelic, rollbar, and sentry are all production-grade monitoring platforms that help frontend teams detect, diagnose, and resolve JavaScript errors and performance issues in real user environments. Each provides SDKs for capturing unhandled exceptions, promise rejections, console errors, and performance metrics like page load times or interaction latencies. They integrate with build tools to enable source map uploads for readable stack traces and support custom error tagging, user identification, and release tracking. While they share core observability goals, they differ significantly in architecture, data model, customization depth, and how they handle edge cases like cross-origin script errors or resource timing.
When your React app throws an uncaught promise rejection in production, which tool gives you the clearest path to root cause? All four platforms — bugsnag, newrelic, rollbar, and sentry — solve the core problem of catching frontend errors, but their approaches to data modeling, performance tracking, and developer experience vary significantly. Let’s compare them through real engineering scenarios.
All four SDKs automatically capture unhandled exceptions and promise rejections, but their initialization patterns differ.
bugsnag requires explicit start() call after configuration:
// bugsnag
import Bugsnag from '@bugsnag/js';
import BugsnagPluginReact from '@bugsnag/plugin-react';
Bugsnag.start({
apiKey: 'YOUR_API_KEY',
plugins: [BugsnagPluginReact],
// Optional: customize error grouping
onError: (event) => {
// Filter out expected errors
if (event.errors[0].errorMessage.includes('ResizeObserver')) return false;
}
});
newrelic uses a global NREUM object before loading the agent:
// newrelic
window.NREUM || (window.NREUM = {});
window.NREUM.init = {
distributed_tracing: { enabled: true },
privacy: { cookies_enabled: false }
};
// Then load newrelic.js script
rollbar initializes with a simple config object:
// rollbar
import Rollbar from 'rollbar';
const rollbar = new Rollbar({
accessToken: 'YOUR_TOKEN',
captureUncaught: true,
captureUnhandledRejections: true,
// Auto-ignore common false positives
ignoredMessages: [/ResizeObserver loop limit exceeded/]
});
sentry uses Sentry.init() with framework-specific integrations:
// sentry
import * as Sentry from '@sentry/react';
Sentry.init({
dsn: 'YOUR_DSN',
integrations: [
new Sentry.BrowserTracing(),
new Sentry.Replay()
],
// Sample rate for performance monitoring
tracesSampleRate: 1.0
});
💡 Key difference: Bugsnag and Sentry offer programmatic hooks (
onError) to filter or enrich errors before sending, while New Relic relies more on post-capture filtering in its UI.
When thousands of users hit the same bug, how does each platform group occurrences?
bugsnag uses a deterministic algorithm based on stack trace similarity and error class. You can override grouping keys:
// bugsnag: Custom grouping
Bugsnag.notify(error, (event) => {
event.groupingHash = `${error.name}-${getRouteName()}`;
});
newrelic groups by error message and stack frame, but offers limited customization. Grouping rules must be configured in the UI.
rollbar uses "fingerprints" derived from stack traces. You can set custom fingerprints:
// rollbar: Custom fingerprint
rollbar.configure({
payload: {
fingerprint: '{{ error.message }}-{{ custom.route }}'
}
});
sentry uses a proprietary algorithm but allows overriding via fingerprint:
// sentry: Custom fingerprint
Sentry.captureException(error, {
fingerprint: ['{{ default }}', getRouteName()]
});
💡 Real-world impact: Bugsnag’s deterministic grouping prevents the "group explosion" problem when minor code changes alter stack traces. Sentry’s approach is more flexible but requires careful fingerprint design.
How do these tools track slow interactions or failed network requests?
bugsnag treats performance separately via @bugsnag/plugin-browser-performance. It captures page loads and route changes but doesn’t auto-instrument XHR/fetch:
// bugsnag: Manual performance span
const span = Bugsnag.performance?.createSpan('checkout-process');
span?.start();
// ... do work
span?.end();
newrelic automatically instruments XHR, fetch, and SPA route changes out of the box. Correlates frontend timings with backend traces:
// newrelic: Automatic - no code needed
// But you can add custom attributes
newrelic.setCustomAttribute('cart_size', cart.items.length);
rollbar focuses primarily on errors. Performance monitoring requires manual instrumentation:
// rollbar: Manual timing
const start = Date.now();
apiCall().finally(() => {
rollbar.log('API call duration', { duration: Date.now() - start });
});
sentry includes automatic Web Vitals, XHR, and navigation tracking via BrowserTracing integration:
// sentry: Auto-instrumented
// Also supports custom spans
const transaction = Sentry.startTransaction({ name: 'Checkout' });
const span = transaction.startChild({ op: 'process_payment' });
// ... work
span.finish();
transaction.finish();
💡 Critical distinction: New Relic and Sentry provide automatic performance instrumentation; Bugsnag requires opt-in plugins; Rollbar expects manual implementation.
What happens when errors come from third-party scripts (CDNs, ads) with no stack traces?
bugsnag captures these as "Script error." but allows enrichment via beforeSend:
// bugsnag: Add context to cross-origin errors
Bugsnag.start({
beforeSend: (report) => {
if (report.events[0].errors[0].errorMessage === 'Script error.') {
report.addMetadata('context', { lastRoute: getCurrentRoute() });
}
}
});
newrelic automatically captures cross-origin errors but shows limited details without CORS headers.
rollbar includes a checkIgnore function to handle these:
// rollbar: Filter or enrich
rollbar.configure({
checkIgnore: (isUncaught, args, payload) => {
if (payload.body.message === 'Script error.') {
payload.custom = { ...payload.custom, route: window.location.pathname };
}
return false; // don't ignore
}
});
sentry uses beforeSend for similar enrichment:
// sentry: Enrich cross-origin errors
Sentry.init({
beforeSend(event) {
if (event.exception?.values?.[0]?.value === 'Script error.') {
event.extra = { ...event.extra, route: window.location.pathname };
}
return event;
}
});
💡 Reality check: All tools struggle with true cross-origin errors without proper CORS headers on scripts. The best practice is adding
crossorigin="anonymous"and CORS headers on your own assets.
How do you get readable stack traces from minified production code?
bugsnag requires uploading source maps via CLI or build plugin:
# bugsnag: Upload via CLI
bugsnag-sourcemaps upload --api-key YOUR_KEY --app-version 1.2.3 \
--minified-url 'https://cdn.example.com/bundle.*.js' \
--source-map bundle.js.map --minified-file bundle.js
newrelic automatically downloads source maps if they’re publicly accessible (not recommended for security). Otherwise, use their upload API.
rollbar supports both public source maps and private uploads via API:
// rollbar: During build
const rollbar = require('rollbar/src/server/rollbar');
rollbar.uploadSourceMaps({
accessToken: 'POST_SERVER_ITEM_TOKEN',
version: process.env.RELEASE_VERSION,
minifiedUrlPrefix: 'https://cdn.example.com/',
directory: 'dist/'
});
sentry has first-class CLI support with framework-specific integrations:
# sentry: Next.js example
npx @sentry/cli releases files 1.2.3 upload-sourcemaps ./build
💡 Pro tip: Sentry and Bugsnag have the most robust source map handling with version-aware matching. New Relic’s auto-download can fail with complex CDN setups.
How well do they handle React’s quirks like component boundaries?
bugsnag provides @bugsnag/plugin-react for error boundaries:
// bugsnag: React error boundary
import { BugsnagErrorBoundary } from '@bugsnag/plugin-react';
function App() {
return (
<BugsnagErrorBoundary>
<MyComponent />
</BugsnagErrorBoundary>
);
}
newrelic doesn’t provide React-specific components. You’d wrap manually:
// newrelic: Manual error boundary
class ErrorBoundary extends React.Component {
componentDidCatch(error) {
newrelic.noticeError(error);
}
// ...
}
rollbar offers rollbar-react for error boundaries:
// rollbar: React wrapper
import { RollbarProvider, ErrorBoundary } from '@rollbar/react';
function App() {
return (
<RollbarProvider instance={rollbar}>
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
</RollbarProvider>
);
}
sentry has deep React integration with component name tracking:
// sentry: Automatic component names in stack traces
import { ErrorBoundary } from '@sentry/react';
function App() {
return (
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
);
}
💡 Key advantage: Sentry and Bugsnag automatically include component names in error contexts. New Relic requires manual instrumentation for equivalent detail.
How do they handle high-volume applications?
bugsnag uses session-based sampling. You can configure error sampling rates:
// bugsnag: Sample 50% of errors
Bugsnag.start({
endpoints: { notify: '...' },
maxEvents: 100 // per session
});
newrelic samples based on account settings. No client-side sampling controls.
rollbar offers occurrence-based pricing with configurable sampling:
// rollbar: Drop 90% of certain errors
rollbar.configure({
itemsPerMinute: 60,
scrubFields: ['password']
});
sentry uses dynamic sampling based on error frequency:
// sentry: Custom sampling
Sentry.init({
sampleRate: 0.5, // 50% of errors
tracesSampleRate: 1.0
});
💡 Strategic note: Bugsnag’s session-centric model helps measure stability (% crash-free sessions), while Sentry/Rollbar focus on error occurrence counts. Choose based on whether you care more about user impact (sessions) or bug frequency (occurrences).
How do they handle sensitive data?
All four support automatic scrubbing of common fields (password, credit_card), but differ in customization:
bugsnag uses redactedKeys:
Bugsnag.start({
redactedKeys: ['email', 'ssn']
});
newrelic uses privacy config:
window.NREUM.init = {
privacy: { cookies_enabled: false },
ajax: { deny_list: ['api/private'] }
};
rollbar uses scrubFields:
rollbar.configure({
scrubFields: ['email', 'token']
});
sentry uses sanitizeKeys:
Sentry.init({
sanitizeKeys: [/email/, /token/]
});
💡 Critical consideration: New Relic’s agent loads a large external script by default, which may violate strict CSP policies. Others offer self-hosted options or smaller bundles.
| Scenario | Best Choice | Why |
|---|---|---|
| Mobile/web hybrid app needing crash-free session metrics | bugsnag | Session-based stability scores align with mobile app store metrics |
| Enterprise using New Relic APM for backend services | newrelic | Unified dashboard for full-stack traces without context switching |
| Small team wanting simple error tracking with legacy browser support | rollbar | Straightforward setup, reliable IE11 support, predictable pricing |
| Complex SPA requiring deep performance insights and debugging | sentry | Web Vitals, session replays, and local variable snapshots accelerate debugging |
Remember: The best monitoring tool is the one your team actually uses to fix bugs. Prioritize actionable alerts over data volume, and always validate that your source maps work in staging before going live.
Choose newrelic if your team already uses New Relic’s APM suite for backend monitoring and wants unified observability across the full stack. Its browser agent excels at correlating frontend performance (like SPA route changes or AJAX timings) with backend traces, but offers less flexibility for custom error instrumentation compared to pure-play error trackers. Best suited for enterprises standardizing on a single vendor for infrastructure, application, and frontend monitoring.
Choose rollbar if you need straightforward error grouping with minimal configuration and strong support for legacy browsers. Its occurrence-based pricing and simple API make it easy to adopt for small-to-mid teams focused primarily on JavaScript error capture rather than deep performance analysis. Rollbar’s automatic source map resolution works reliably out of the box, but advanced features like custom telemetry pipelines require more manual setup than competitors.
Choose bugsnag if you prioritize deterministic error grouping, fine-grained control over error reporting logic, and a clean separation between error and performance telemetry. Its session-based stability score and built-in release health metrics are particularly valuable for mobile and desktop apps where crash-free sessions matter more than individual error counts. The SDK’s modular design lets you disable features like breadcrumbs or network capture without affecting core error handling.
Choose sentry if you want the most comprehensive frontend observability platform with deep framework integrations (React, Vue, Angular), rich performance tracing (including Web Vitals), and powerful debugging features like local variable snapshots in stack traces. Its open-source roots and extensive plugin ecosystem make it highly extensible, though this flexibility can increase configuration complexity. Ideal for engineering teams that treat frontend monitoring as a first-class concern alongside backend observability.
This package instruments your application for performance monitoring with New Relic.
In order to take full advantage of this package, make sure you have a New Relic account before starting.
As with any instrumentation tool, please test before using in production.
To use New Relic's Node.js agent entails these three steps, which are described in detail below:
newrelic packageTo install the agent for performance monitoring, use your favorite npm-based package manager and install the newrelic package into your application:
$ npm install newrelic
Then, copy the stock configuration file to your program's base folder:
$ cp ./node_modules/newrelic/newrelic.js ./<your destination>
Now, add your New Relic license key and application/service name to that file:
/* File: newrelic.js */
'use strict'
/**
* New Relic agent configuration.
*
* See lib/config/default.js in the agent distribution for a more complete
* description of configuration variables and their potential values.
*/
exports.config = {
app_name: ['Your application or service name'],
license_key: 'your new relic license key',
/* ... rest of configuration .. */
}
Finally, run your program with the newrelic module loaded first by using node's -r/--require flag.
$ node -r newrelic your-program.js
If you cannot control how your program is run, you can load the newrelic module before any other module in your program.
const newrelic = require('newrelic')
/* ... the rest of your program ... */
Note: The minimum supported Next.js version is 12.0.9. If you are using Next.js middleware the minimum supported version is 12.2.0.
The New Relic Node.js agent provides instrumentation for Next.js The instrumentation provides telemetry for server-side rendering via getServerSideProps, middleware (limited to Next.js versions 12.2.0 - 13.4.12), and New Relic transaction naming for both page and server requests. It does not provide any instrumentation for actions occurring during build or in client-side code. If you want telemetry data on actions occurring on the client (browser), you can inject the browser agent.
Here are documents for more in-depth explanations about transaction naming, and segments/spans.
Typically you are running a Next.js app with the next cli and you must load the agent via NODE_OPTIONS:
NODE_OPTIONS='-r newrelic' next start
If you are having trouble getting the newrelic package to instrument Next.js, take a look at our FAQs.
The following example applications show how to load the newrelic instrumentation, inject browser agent, and handle errors:
If you are using next as a custom server, you're probably not running your application with the next CLI. In that scenario we recommend running the Next.js instrumentation as follows.
node -r newrelic your-program.js
If your application is written with import and export statements in javascript, you are using ES Modules and must bootstrap the agent in a different way.
The New Relic Node.js agent includes support for ES Modules.
If you rely on a configuration file to run the agent, you must rename the file from newrelic.js to newrelic.cjs so it can be properly loaded. All the contents of the configuration file will behave the same once you rename. See CommonJS modules in ESM for more details.
$ mv newrelic.js newrelic.cjs
To use the newrelic ESM loader, start your program with node and use the --import flag and a path to the loader file, like this:
$ node --import newrelic/esm-loader.mjs -r newrelic your-program.js
The agent supports adding your own custom instrumentation to ES module applications. You can use the instrumentation API methods. The only other difference between CommonJS custom instrumentation and ESM is you must provide a property of isEsm: true.
import newrelic from 'newrelic'
newrelic.instrument({ moduleName: 'parse-json', isEsm: true }, function wrap(shim, parseJson, moduleName) {
shim.wrap(parseJson.default, function wrapParseJson(shim, orig) {
return function wrappedParseJson() {
const result = orig.apply(this, arguments)
result.instrumented = true
return true
}
})
})
We support the following custom instrumentation API methods in ES module apps:
newrelic.instrumentnewrelic.instrumentConglomeratenewrelic.instrumentDatastorenewrelic.instrumentMessagesnewrelic.instrumentWebframeworkNote that we do not support newrelic.instrumentLoadedModule, for the same issue of immutability mentioned above.
If you want to see an example of how to write custom instrumentation in an ES module app, check out our examples repo for a working demo.
For more information on getting started, check the Node.js docs.
There are modules that can be installed and configured to accompany the Node.js agent:
@newrelic/apollo-server-plugin: New Relic's official Apollo Server plugin for use with the Node.js agent.There are modules included within the Node.js agent to add more instrumentation for 3rd party modules:
@newrelic/native-metrics: Provides hooks into the native v8 layer of Node.js to provide metrics to the Node.js agent.The newrelic module returns an object with the Node.js agent's API methods attached.
const newrelic = require('newrelic')
/* ... */
newrelic.addCustomAttribute('some-attribute', 'some-value')
You can read more about using the API over on the New Relic documentation site.
These are the steps to work on core agent features, with more detail below:
npmFork and clone this GitHub repository:
$ git clone git@github.com:your-user-name/node-newrelic.git
$ cd node-newrelic
Install the project's dependencies:
$ npm install
Then you're all set to start programming.
$ npm run services$ npm run testAvailable test suites include:
$ npm run unit
$ npm run integration
$ npm run versioned
$ npm run lint
$ npm run smoke
Here are some resources for learning more about the agent:
Configuring the agent using newrelic.js or environment variables
Example applications - Working examples of New Relic features in Node.js.
Should you need assistance with New Relic products, you are in good hands with several support channels.
If the issue has been confirmed as a bug or is a feature request, please file a GitHub issue.
Support Channels
At New Relic we take your privacy and the security of your information seriously, and are committed to protecting your information. We must emphasize the importance of not sharing personal data in public forums, and ask all users to scrub logs and diagnostic information for sensitive information, whether personal, proprietary, or otherwise.
We define “Personal Data” as any information relating to an identified or identifiable individual, including, for example, your name, phone number, post code or zip code, Device ID, IP address and email address.
Please review New Relic’s General Data Privacy Notice for more information.
We encourage your contributions to improve the Node.js agent! Keep in mind when you submit your pull request, you'll need to sign the CLA via the click-through using CLA-Assistant. You only have to sign the CLA one time per project.
If you have any questions, or to execute our corporate CLA, required if your contribution is on behalf of a company, please drop us an email at opensource@newrelic.com.
A note about vulnerabilities
As noted in our security policy, New Relic is committed to the privacy and security of our customers and their data. We believe that providing coordinated disclosure by security researchers and engaging with the security community are important means to achieve our security goals.
If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through our bug bounty program.
If you would like to contribute to this project, review these guidelines.
To all contributors, we thank you! Without your contribution, this project would not be what it is today.
Except as noted below, the Node.js agent is licensed under the Apache 2.0 License.
The New Relic security agent is licensed under the New Relic Software License v1.0. The New Relic security agent module may be integrated like the New Relic Node.js agent.
The Node.js agent also uses source code from third-party libraries. You can find full details on which libraries are used and the terms under which they are licensed in the third-party notices document.