Sentry SDK Setup
Detect a project's framework and runtime, then install and configure the correct Sentry SDK with sensible, production-ready defaults: client initialization, DSN via environment variable, error capture, performance/tracing, and source map upload so stack traces are readable.
Consolidation note
The upstream sentry@claude-plugins-official plugin ships ~30 separate
per-SDK setup skills (one per framework/runtime). This single Lisa-native
skill consolidates all of them: instead of one thin skill per SDK, it detects the
framework and applies the matching case below. The behavior is reimplemented from
scratch against Lisa conventions — it is not a translation of the upstream
skills. Pinned to sentry@claude-plugins-official@1.0.0 via synced-from so the
parity drift detector tracks it as one unit.
Step 1 — Detect framework & runtime
Inspect the project before choosing an SDK. Read package.json
(dependencies/scripts), config files, and lockfiles:
nextdependency ornext.config.*→ Next.js@nestjs/core→ NestJSreact-native/expo→ React Native / Exporeact+ a bundler (vite/webpack) without Next → React (browser)express/fastify/koaand a Node entrypoint → Node servervue/@angular/core/svelte→ that browser frameworkpyproject.toml/requirements.txt;django/flask/fastapi→ Python (and which web framework)- A plain Node library/CLI → Node
If the runtime is genuinely ambiguous, ask which app to instrument rather than guessing. Respect the project's package manager (bun/npm/pnpm/yarn — match the lockfile) and module system (ESM vs CJS).
Step 2 — Install the package
Use the project's package manager. Examples (swap bun add for your manager):
| Framework | Package |
|---|---|
| React (browser) | @sentry/react |
| Next.js | @sentry/nextjs |
| Node / Express / Fastify | @sentry/node (+ @sentry/profiling-node for profiling) |
| NestJS | @sentry/nestjs (+ @sentry/node) |
| React Native / Expo | @sentry/react-native |
| Vue | @sentry/vue |
| Angular | @sentry/angular |
| Svelte / SvelteKit | @sentry/svelte / @sentry/sveltekit |
| Python (generic) | sentry-sdk |
| Django | sentry-sdk[django] |
| Flask | sentry-sdk[flask] |
| FastAPI | sentry-sdk[fastapi] |
For Next.js, prefer the official wizard when available — it scaffolds the config files and source-map upload for you:
npx @sentry/wizard@latest -i nextjs
Step 3 — Initialize the client
Initialize as early as possible in the app's lifecycle, before other code runs. Always read the DSN from the environment (see Step 4) — never hard-code it.
React (browser) — src/instrument.ts, imported first in the entrypoint:
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
integrations: [Sentry.browserTracingIntegration()],
tracesSampleRate: 0.1, // tune per traffic; 1.0 in dev
});
Node / Express — instrument.ts, required at the very top of the entrypoint
(import "./instrument"; must be the first import):
import * as Sentry from "@sentry/node";
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 0.1,
});
Then, after routes are defined: Sentry.setupExpressErrorHandler(app);
NestJS — import ./instrument first in main.ts, then add Sentry's module:
// main.ts — FIRST line
import "./instrument";
// ...
// app.module.ts
import { SentryModule } from "@sentry/nestjs/setup";
@Module({ imports: [SentryModule.forRoot()] })
export class AppModule {}
Next.js — config lives in sentry.client.config.ts,
sentry.server.config.ts, sentry.edge.config.ts, and next.config.js is
wrapped with withSentryConfig. The wizard (Step 2) writes these; verify the DSN
is read from process.env.NEXT_PUBLIC_SENTRY_DSN / process.env.SENTRY_DSN.
React Native / Expo — wrap the root component:
import * as Sentry from "@sentry/react-native";
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN,
tracesSampleRate: 0.2,
});
export default Sentry.wrap(App);
Python (Django/Flask/FastAPI/generic) — initialize at startup
(settings.py, app factory, or main module):
import os
import sentry_sdk
sentry_sdk.init(
dsn=os.environ["SENTRY_DSN"],
environment=os.environ.get("ENVIRONMENT", "production"),
traces_sample_rate=0.1,
send_default_pii=False,
)
Framework-specific integrations (e.g. DjangoIntegration, FastApiIntegration)
are auto-enabled by the matching extra installed in Step 2.
Step 4 — DSN via environment
- Store the DSN in an environment variable, never in committed source.
- Add it to
.env.example(with a placeholder) so the requirement is documented, but keep the real value in.env/secrets and confirm.envis gitignored. - Use the framework's public-env convention for client-side code:
NEXT_PUBLIC_SENTRY_DSN(Next.js),VITE_SENTRY_DSN(Vite),EXPO_PUBLIC_SENTRY_DSN(Expo). Server-only code usesSENTRY_DSN. - For source-map upload (Step 6) the build also needs
SENTRY_AUTH_TOKEN,SENTRY_ORG, andSENTRY_PROJECT— these are build/CI secrets, not shipped to the client.
Step 5 — Error + performance monitoring
- Errors: unhandled exceptions/rejections are captured automatically once
initruns; add the framework error handler where required (Express:setupExpressErrorHandler; React: an error boundary viaSentry.ErrorBoundary; NestJS:SentryModule). UseSentry.captureException(err)for caught-but-notable errors. - Performance/tracing: set a
tracesSampleRate(start ~0.1 in production,1.0in dev) and enable the framework tracing integration (browser tracing, HTTP/DB auto-instrumentation on the server). Optionally add profiling on Node via@sentry/profiling-nodeandprofilesSampleRate. - Set
environmentand (ideally)releaseso issues are grouped per deploy.
Step 6 — Source maps (readable stack traces)
Minified/transpiled traces are useless without source maps. Configure upload at build time:
- Next.js: handled by
withSentryConfiginnext.config.js(the wizard sets it up); ensureSENTRY_AUTH_TOKEN/SENTRY_ORG/SENTRY_PROJECTexist in CI. - Vite/Webpack/Rollup/esbuild: add the Sentry bundler plugin
(
@sentry/vite-plugin,@sentry/webpack-plugin, etc.) withsourcemapsupload enabled and the same auth env vars. - Node: build with source maps emitted and upload via
sentry-cli sourcemaps upload(or the bundler plugin) in the release step. - React Native: source maps upload through the Sentry Metro/Gradle/Xcode integration added by the SDK's setup.
- Tie uploads to a release identifier (commit SHA or version) and inject the
same release into
Sentry.init({ release })so traces map to the right build.
Step 7 — Verify
- Build/typecheck to confirm the SDK wiring compiles:
bun run build/bun run typecheck(or the project's equivalents). - Trigger a deliberate test error in a non-production environment and confirm it appears in Sentry with a readable (source-mapped) stack trace.
- Confirm a transaction/trace shows up to validate performance monitoring.
- Remove the test error afterward.
Rules
- Do not port or copy upstream plugin code — reimplement from scratch.
- Never hard-code or commit a DSN or
SENTRY_AUTH_TOKEN; route everything through env/secrets and update.env.example. - Match the project's package manager and module system; do not introduce a new one to install Sentry.
- Initialize Sentry before any other application code runs.
- Tune sample rates for the environment — do not ship
tracesSampleRate: 1.0to high-traffic production by default. - Verify with a real captured event and a source-mapped trace before declaring setup complete.