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):
Integration Size When to Use Core SDK ~25 KB Always browserTracingIntegration ~8 KB Performance monitoring replayIntegration ~35 KB Session replay feedbackIntegration ~15 KB User feedback replayCanvasIntegration ~10 KB Canvas recording in replay captureConsoleIntegration ~2 KB Console log capture httpClientIntegration ~3 KB HTTP breadcrumbs
Best Practices
Audit integrations regularly
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?
];
Use code splitting for heavy features
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 ());
}
Consider CDN for prototyping
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.
Monitor bundle size in CI
Add bundle size checks to prevent regressions:
Don't over-optimize at the expense of functionality
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