Skip to main content

Best Error Tracking Libraries for JavaScript in 2026

·PkgPulse Team

TL;DR

Sentry for the best developer experience and ecosystem; Highlight.io for session replay + errors in one tool. Sentry (~4M weekly downloads) is the industry standard — integrations for every framework, source maps, performance monitoring, and a generous free tier (5K errors/mo). Highlight.io (~50K downloads) is newer and open-source — it combines error tracking with full session replay at a lower price. For most projects, Sentry is the safe bet.

Key Takeaways

  • Sentry: ~4M weekly downloads — full-featured, 5K errors/mo free, every framework
  • Highlight.io: ~50K downloads — open-source, session replay + errors + logs bundled
  • Bugsnag: ~200K downloads — stability monitoring focus, good mobile support
  • Sentry source maps — upload during build to see original TypeScript code in errors
  • @sentry/nextjs — automatic route instrumentation, server + client errors unified

Sentry (Industry Standard)

// Sentry — Next.js setup
// npm install @sentry/nextjs
// npx @sentry/wizard@latest -i nextjs

// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  environment: process.env.NODE_ENV,
  tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
  replaysSessionSampleRate: 0.1,     // 10% of sessions
  replaysOnErrorSampleRate: 1.0,     // 100% of error sessions
  integrations: [
    Sentry.replayIntegration({
      maskAllText: true,             // Privacy: mask all user text
      blockAllMedia: true,
    }),
  ],
});
// sentry.server.config.ts
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 0.1,
  // Profiling (requires plan)
  profilesSampleRate: 0.1,
});
// Sentry — manual error capture and context
import * as Sentry from '@sentry/nextjs';

// Capture specific errors with context
async function processPayment(userId: string, amount: number) {
  try {
    await chargeCard(userId, amount);
  } catch (error) {
    Sentry.captureException(error, {
      tags: {
        feature: 'payments',
        userId,
      },
      extra: {
        amount,
        timestamp: new Date().toISOString(),
      },
      level: 'error',
    });
    throw error;
  }
}

// Set user context (shows in Sentry UI)
Sentry.setUser({
  id: user.id,
  email: user.email,
  username: user.name,
});

// Custom breadcrumbs
Sentry.addBreadcrumb({
  category: 'ui.click',
  message: 'User clicked checkout button',
  level: 'info',
});

// Performance spans
const transaction = Sentry.startTransaction({ name: 'processOrder' });
const span = transaction.startChild({ op: 'validateInventory' });
await checkInventory(items);
span.finish();
transaction.finish();
// Sentry — error boundary (React)
import * as Sentry from '@sentry/react';

export function ErrorBoundaryWrapper({ children }) {
  return (
    <Sentry.ErrorBoundary
      fallback={({ error, resetError }) => (
        <div>
          <h2>Something went wrong</h2>
          <pre>{error.message}</pre>
          <button onClick={resetError}>Try again</button>
        </div>
      )}
      beforeCapture={(scope, error, componentStack) => {
        scope.setTag('react_component', 'App');
      }}
    >
      {children}
    </Sentry.ErrorBoundary>
  );
}

Highlight.io (Open-Source, Session Replay)

// Highlight.io — setup with React
import { H } from 'highlight.run';

H.init(process.env.NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID!, {
  environment: 'production',
  version: process.env.NEXT_PUBLIC_APP_VERSION,
  networkRecording: {
    enabled: true,
    recordHeadersAndBody: true,   // Record network requests
  },
  privacySetting: 'strict',        // Mask PII by default
});

// Identify user
H.identify(user.email, {
  id: user.id,
  name: user.name,
  plan: user.plan,
});

// Manual error
try {
  await riskyOperation();
} catch (err) {
  H.consumeError(err as Error, {
    payload: { operation: 'riskyOperation' },
  });
}

// Track custom events
H.track('Checkout Started', { items: cart.length, total: cart.total });
// Highlight.io — Node.js backend
import { H } from '@highlight-run/node';

H.init({ projectID: process.env.HIGHLIGHT_PROJECT_ID! });

// Express middleware
app.use(H.Handlers.errorHandler());

// Manual capture
H.consumeError(new Error('Payment failed'), 'user@example.com', {
  payload: { amount: 99.99 },
});

Source Maps (Critical for Any Tool)

// next.config.js — automatic source map upload with Sentry
const { withSentryConfig } = require('@sentry/nextjs');

module.exports = withSentryConfig({
  /* next.js config */
}, {
  // Sentry webpack plugin options
  silent: true,
  org: 'my-org',
  project: 'my-project',
  // Automatically upload source maps after each build
  widenClientFileUpload: true,
  // Delete source maps from bundle (don't expose to users)
  hideSourceMaps: true,
});

When to Choose

ScenarioPick
Standard error trackingSentry
Session replay + errors + logsHighlight.io
Open-source, self-hostableHighlight.io
Mobile apps (React Native + web)Bugsnag or Sentry
Stability score / error budgetBugsnag
Performance monitoringSentry (transactions + spans)
Free tier (small project)Sentry (5K errors/mo free)
Enterprise SLASentry or Datadog

Compare error tracking library package health on PkgPulse.

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.