Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/getsentry/sentry-javascript/llms.txt

Use this file to discover all available pages before exploring further.

The Sentry JavaScript SDK is designed to be lightweight, but you can further optimize bundle size by customizing integrations and using tree-shaking.

Bundle Size Impact

Typical bundle sizes (gzipped):
  • Browser SDK (minimal): ~25 KB
  • Browser SDK (with integrations): ~35-45 KB
  • Node SDK: Not relevant for frontend bundles
  • Framework SDKs: Similar to Browser SDK + framework-specific code
The SDK’s bundle size impact is usually minimal compared to other dependencies like React, Vue, or large utility libraries.

Tree-Shaking

Modern bundlers automatically remove unused code:
// ✅ Good: Named imports enable tree-shaking
import { init, browserTracingIntegration } from '@sentry/browser';

init({
  dsn: '__DSN__',
  integrations: [browserTracingIntegration()],
});

// ❌ Bad: Namespace imports may include more code
import * as Sentry from '@sentry/browser';

Sentry.init({
  dsn: '__DSN__',
  integrations: [Sentry.browserTracingIntegration()],
});
While namespace imports (import * as Sentry) are convenient and recommended for better DX, named imports (import { init }) may result in slightly smaller bundles with some bundlers.

Selective Integration Loading

Minimal SDK

Disable default integrations and add only what you need:
import {
  init,
  globalHandlersIntegration,
  breadcrumbsIntegration,
} from '@sentry/browser';

init({
  dsn: '__DSN__',
  defaultIntegrations: false, // Disable all defaults
  integrations: [
    // Add only what you need
    globalHandlersIntegration(),
    breadcrumbsIntegration(),
  ],
});

Conditional Integration Loading

Load heavy integrations only when needed:
import { init } from '@sentry/browser';

const integrations = [];

// Always include core integrations
import { globalHandlersIntegration } from '@sentry/browser';
integrations.push(globalHandlersIntegration());

// Conditionally add Replay (larger bundle)
if (shouldEnableReplay) {
  const { replayIntegration } = await import('@sentry-internal/replay');
  integrations.push(replayIntegration());
}

init({
  dsn: '__DSN__',
  integrations,
});

Lazy Loading Sentry

Load Sentry asynchronously to improve initial page load:
// Load Sentry after initial render
window.addEventListener('load', async () => {
  const Sentry = await import('@sentry/browser');
  
  Sentry.init({
    dsn: '__DSN__',
  });
});
Lazy loading means errors during initial page load won’t be captured. Only use this if initial load performance is critical.

Smart Lazy Loading

Load immediately on errors, lazily otherwise:
let sentryLoaded = false;

async function loadSentry() {
  if (sentryLoaded) return;
  
  const Sentry = await import('@sentry/browser');
  Sentry.init({ dsn: '__DSN__' });
  sentryLoaded = true;
}

// Load on error
window.addEventListener('error', loadSentry);
window.addEventListener('unhandledrejection', loadSentry);

// Load after idle
if ('requestIdleCallback' in window) {
  requestIdleCallback(loadSentry);
} else {
  setTimeout(loadSentry, 1000);
}

CDN Loading

Use the Sentry CDN bundle to avoid bundling:
<script
  src="https://browser.sentry-cdn.com/8.0.0/bundle.tracing.replay.min.js"
  integrity="sha384-..."
  crossorigin="anonymous"
></script>

<script>
  Sentry.init({
    dsn: '__DSN__',
  });
</script>

Available CDN Bundles

<!-- Minimal bundle -->
<script src="https://browser.sentry-cdn.com/8.0.0/bundle.min.js"></script>

<!-- With performance monitoring -->
<script src="https://browser.sentry-cdn.com/8.0.0/bundle.tracing.min.js"></script>

<!-- With session replay -->
<script src="https://browser.sentry-cdn.com/8.0.0/bundle.replay.min.js"></script>

<!-- With both -->
<script src="https://browser.sentry-cdn.com/8.0.0/bundle.tracing.replay.min.js"></script>

<!-- With feedback widget -->
<script src="https://browser.sentry-cdn.com/8.0.0/bundle.feedback.min.js"></script>

Framework-Specific Optimizations

React

Only import what you need:
import { init, reactRouterV6BrowserTracingIntegration } from '@sentry/react';
import { useEffect } from 'react';
import {
  useLocation,
  useNavigationType,
  createRoutesFromChildren,
  matchRoutes,
} from 'react-router-dom';

init({
  dsn: '__DSN__',
  integrations: [
    reactRouterV6BrowserTracingIntegration({
      useEffect,
      useLocation,
      useNavigationType,
      createRoutesFromChildren,
      matchRoutes,
    }),
  ],
});

Next.js

Next.js SDK is optimized automatically:
// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: '__DSN__',
  // Tree-shaking happens automatically
});
Further optimization:
// next.config.js
const { withSentryConfig } = require('@sentry/nextjs');

module.exports = withSentryConfig(
  {
    // Next.js config
  },
  {
    // Sentry config
    silent: true,
    
    // Exclude source maps from bundle
    widenClientFileUpload: true,
    hideSourceMaps: true, // Available in v7
  }
);

Vue

import { init, browserTracingIntegration } from '@sentry/vue';

init({
  app,
  dsn: '__DSN__',
  integrations: [
    browserTracingIntegration({ router }), // Only if using Vue Router
  ],
});

Bundler Configuration

Webpack

Optimize tree-shaking:
// webpack.config.js
module.exports = {
  optimization: {
    usedExports: true,
    sideEffects: false,
  },
};

Vite

Vite optimizes automatically, but you can verify:
// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          // Separate Sentry into its own chunk
          sentry: ['@sentry/browser'],
        },
      },
    },
  },
});

Rollup

// rollup.config.js
import { terser } from 'rollup-plugin-terser';

export default {
  plugins: [
    terser({
      compress: {
        pure_funcs: ['console.log'], // Remove debug logs
      },
    }),
  ],
};

Feature Flags for Bundle Size

Disable Debug Code in Production

The SDK includes debug code that’s stripped in production:
import { init } from '@sentry/browser';

init({
  dsn: '__DSN__',
  debug: false, // Ensure debug is off in production
});

Environment-Based Loading

if (process.env.NODE_ENV === 'production') {
  import('@sentry/browser').then((Sentry) => {
    Sentry.init({ dsn: '__DSN__' });
  });
}

Measuring Bundle Size

webpack-bundle-analyzer

npm install --save-dev webpack-bundle-analyzer
// webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin(),
  ],
};

Vite Plugin Visualizer

npm install --save-dev rollup-plugin-visualizer
// vite.config.js
import { visualizer } from 'rollup-plugin-visualizer';

export default {
  plugins: [
    visualizer({ open: true }),
  ],
};

Bundle Size Limit

Set size limits to prevent regressions:
npm install --save-dev size-limit @size-limit/preset-app
// package.json
{
  "size-limit": [
    {
      "path": "dist/bundle.js",
      "limit": "100 KB"
    }
  ]
}

Integration Size Reference

Approximate sizes (gzipped):
IntegrationSizeWhen to Use
Core SDK~25 KBAlways
browserTracingIntegration~8 KBPerformance monitoring
replayIntegration~35 KBSession replay
feedbackIntegration~15 KBUser feedback
replayCanvasIntegration~10 KBCanvas recording in replay
captureConsoleIntegration~2 KBConsole log capture
httpClientIntegration~3 KBHTTP breadcrumbs

Best Practices

Review which integrations you’re using and remove unused ones:
// Review this list periodically
const integrations = [
  globalHandlersIntegration(),     // ✅ Needed
  breadcrumbsIntegration(),        // ✅ Needed
  browserTracingIntegration(),     // ❓ Still using?
  replayIntegration(),             // ❓ Still needed?
];
Load heavy integrations dynamically:
// Only load replay when needed
async function enableReplay() {
  const { replayIntegration } = await import('@sentry-internal/replay');
  const client = Sentry.getClient();
  client.addIntegration(replayIntegration());
}
During development, use CDN bundles to avoid build config:
<!-- Quick setup -->
<script src="https://browser.sentry-cdn.com/8.0.0/bundle.min.js"></script>
Switch to npm package for production for better bundling control.
Add bundle size checks to prevent regressions:
npm run size-limit
The SDK’s impact is usually minimal. Removing error reporting to save 25 KB is rarely worth it.

Complete Minimal Example

// Smallest possible Sentry setup
import {
  init,
  createTransport,
  makeFetchTransport,
} from '@sentry/browser';

init({
  dsn: '__DSN__',
  
  // Disable all default integrations
  defaultIntegrations: false,
  
  // Minimal transport
  transport: makeFetchTransport,
  
  // No performance monitoring
  enableTracing: false,
});

// This setup is < 20 KB gzipped
// Only captures manually sent events

Production-Optimized Example

import {
  init,
  browserTracingIntegration,
  globalHandlersIntegration,
  breadcrumbsIntegration,
  dedupeIntegration,
} from '@sentry/browser';

const isProd = process.env.NODE_ENV === 'production';

init({
  dsn: '__DSN__',
  environment: process.env.NODE_ENV,
  debug: !isProd,
  
  // Only essential integrations
  defaultIntegrations: false,
  integrations: [
    globalHandlersIntegration(),
    breadcrumbsIntegration(),
    dedupeIntegration(),
    browserTracingIntegration(),
  ],
  
  // Lower sampling in production
  tracesSampleRate: isProd ? 0.05 : 1.0,
  
  // Minimal breadcrumbs
  maxBreadcrumbs: 25,
});

// Load replay only when needed
if (userWantsReplay) {
  import('@sentry-internal/replay').then(({ replayIntegration }) => {
    Sentry.getClient().addIntegration(replayIntegration());
  });
}

// ~30 KB gzipped with tracing, ~25 KB without

Next Steps

Source Maps

Configure source maps for production

Performance Monitoring

Optimize performance monitoring

Build docs developers (and LLMs) love