Netwarden
Back to Blog
tutorials

Migrating from Sentry to Netwarden in 30 minutes

Step-by-step guide to swap @sentry/browser for @netwarden/sdk. SDK init shape, source-map upload, release tagging, and the 5 things that need a manual touch.

Netwarden TeamMay 8, 202610 min read
sentry migrationerror tracking migration@netwarden/sdksource maps
Share this article:

Migrating from Sentry to Netwarden in 30 minutes

If you've already decided to leave Sentry — for the pricing reasons, or because you want a tool that also pages you on dependency CVEs, or because you want to self-host on a single binary — this post is the concrete migration path.

Most of it is mechanical search-and-replace. The Netwarden JS SDK was deliberately shaped to mirror Sentry's surface so the swap is short. There are five spots where a manual decision is required, and they're all about features Netwarden doesn't ship rather than things that broke. Those are listed at the end.

Total time for a typical Next.js or Express app: about 30 minutes, including the source-map setup. If you're migrating a monorepo with five projects, multiply by three (most of the time per project goes to deployment-pipeline updates, not the SDK swap itself).

Before you start

What you'll need:

  • A Netwarden account. Sign up at app.netwarden.com — Free tier covers one project with no card.
  • Your existing Sentry-using codebase. JavaScript / Node or Python; mobile SDKs are not yet shipped.
  • 30 minutes of focused time.
  • Your build pipeline credentials, if you do source-map upload at deploy time.

What you should know going in:

  • The Netwarden SDK config surface is intentionally smaller than Sentry's. Six core config keys, not thirty. The keys we don't honor map to features we don't have.
  • Sentry's DSN format and Netwarden's DSN format are similar enough that the swap is mostly mechanical.
  • You can keep Sentry running in parallel during the cutover. The two SDKs don't conflict.

Step 1: install the SDK

For JavaScript / Node:

npm install @netwarden/sdk
# or
pnpm add @netwarden/sdk
# or
bun add @netwarden/sdk

For Python:

pip install netwarden
# or
poetry add netwarden

Both packages are MIT-licensed, zero peer dependencies, dual-target (browser + Node) for the JS package. Bundle size for the browser build is about 5 KB gzipped; the Node build is similar. Sentry's bundle is in the 30-40 KB range with the default integrations enabled, so this is a nice side benefit if you care about your initial-load JS budget.

Step 2: swap the init call

This is the largest single change. Side-by-side:

// Before — Sentry
import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "https://[email protected]/456",
  environment: process.env.NODE_ENV,
  release: process.env.RELEASE,
  sampleRate: 1.0,
  tracesSampleRate: 0.1,
  beforeSend(event) {
    if (event.user) delete event.user.email;
    return event;
  },
});
// After — Netwarden
import { init } from "@netwarden/sdk";

init({
  dsn: process.env.NETWARDEN_DSN,
  environment: process.env.NODE_ENV,
  release: process.env.RELEASE,
  sampleRate: 1.0,
  tracesSampleRate: 0.1,
  beforeSend(event) {
    if (event.user) delete event.user.email;
    return event;
  },
});

The six config keys we honor: dsn, environment, release, sampleRate, tracesSampleRate, beforeSend. They behave the same as in Sentry.

The keys we explicitly do not honor:

  • integrations — we ship a fixed set of capture sources (window.onerror, unhandledrejection, process.on('uncaughtException'), Next.js instrumentation.ts hooks). No plugin system.
  • replay, replaysSessionSampleRate, replaysOnErrorSampleRate — no replay product.
  • profilesSampleRate — no profiling product.
  • enableTracing, tracePropagationTargets — no distributed tracing.
  • autoSessionTracking, sendDefaultPii — different defaults; both are off and not configurable in v1.

If your existing init contains any of those, drop them. Each one corresponds to a feature Netwarden does not ship, so there's no behavior to migrate. The product reality is in the launch post and the Apps features page.

For Python:

# Before — Sentry
import sentry_sdk
sentry_sdk.init(
    dsn="https://[email protected]/456",
    environment=os.environ.get("ENV"),
    release=os.environ.get("RELEASE"),
    traces_sample_rate=0.1,
)

# After — Netwarden
from netwarden import init
init(
    dsn=os.environ["NETWARDEN_DSN"],
    environment=os.environ.get("ENV"),
    release=os.environ.get("RELEASE"),
    traces_sample_rate=0.1,
)

Flask, FastAPI, and Django middlewares are auto-detected on init. The Django async-views path is the rougher one in alpha — synchronous Django works cleanly today.

Step 3: swap the capture calls

This is the part that's almost entirely search-and-replace.

// Before
Sentry.captureException(err);
Sentry.captureMessage("user did the thing", "info");
Sentry.setUser({ id: userId, email });
Sentry.setContext("billing", { plan: "studio" });
Sentry.addBreadcrumb({ category: "auth", message: "login attempt" });
Sentry.withScope((scope) => {
  scope.setTag("feature", "checkout");
  Sentry.captureException(err);
});

// After
import * as netwarden from "@netwarden/sdk";

netwarden.captureException(err);
netwarden.captureMessage("user did the thing", "info");
netwarden.setUser({ id: userId, email });
netwarden.setContext("billing", { plan: "studio" });
netwarden.addBreadcrumb({ category: "auth", message: "login attempt" });
netwarden.withScope((scope) => {
  scope.setTag("feature", "checkout");
  netwarden.captureException(err);
});

Same shapes, same semantics. A literal find-and-replace from Sentry. to netwarden. (with the import line updated) covers most codebases. The patterns that don't translate:

  • Sentry.startTransaction(...) and the related transaction/span APIs — no distributed tracing in v1, so these should be deleted rather than translated. If you used them for performance instrumentation, the closest Netwarden equivalent is the request-timing data automatically attached to errors.
  • Sentry.captureFeedback(...) — no user-feedback widget. Wire your own form to email or a webhook if you need it.

For most apps, the diff is dozens of lines of mechanical change and zero lines of "this needs a real refactor."

Step 4: source-map upload

Sentry uses @sentry/cli. Netwarden uses @netwarden/cli. Same idea, similar flags.

# Before — Sentry
npm install --save-dev @sentry/cli
sentry-cli releases new "$RELEASE"
sentry-cli releases files "$RELEASE" upload-sourcemaps ./dist
sentry-cli releases finalize "$RELEASE"
# After — Netwarden
npm install --save-dev @netwarden/cli
netwarden releases new "$RELEASE"
netwarden upload-maps --release "$RELEASE" --dir ./dist
netwarden releases finalize "$RELEASE"

The upload-maps command takes the source-map directory, your release identifier, and an auth token (NETWARDEN_AUTH_TOKEN env var, generated in Settings → SDK Tokens). Behavior on the platform side is the same: maps are stored, indexed by release, and applied at symbolication time when a stack trace comes in for that release.

Build-tool integration:

  • Vite — drop the @netwarden/vite-plugin into vite.config.js. Same shape as @sentry/vite-plugin.
  • Webpack@netwarden/webpack-plugin. Same as Sentry's.
  • Next.js@netwarden/next-plugin wraps next.config.js. Auto-detects build output, auto-uploads on next build. Vercel deploy-hook auto-upload is the supported shortcut path; if you're on Vercel you can skip the CLI entirely.
  • Esbuild, Rollup, Turbopack — run the CLI manually after build. Same as your existing Sentry setup if you weren't using their plugin.

If your existing Sentry setup is "post-build script that runs sentry-cli," the diff is one-line — change the binary name and the env-var name. If you used a Sentry build-tool plugin, the diff is one config block.

Step 5: release tagging

Same pattern as Sentry. Set the release config key to a stable identifier — typically your git SHA or your CI build number.

# In CI
RELEASE=$(git rev-parse HEAD)
NETWARDEN_RELEASE=$RELEASE npm run build
netwarden upload-maps --release "$RELEASE" --dir ./dist
// In code
init({
  dsn: process.env.NETWARDEN_DSN,
  release: process.env.NETWARDEN_RELEASE,
});

Auto-reopen logic uses release identity: when a previously resolved issue regresses in a new release, the issue auto-reopens and pages whoever owns it. Same as Sentry.

The five things that need a manual touch

These are the spots where the migration is not search-and-replace, because the underlying feature in Sentry doesn't have a Netwarden equivalent. Treat each one as a decision rather than a translation.

  1. Sentry session replays. Netwarden has no replay product and won't soon — the storage cost is at odds with $9/month pricing. Decide if you can live without. For solo devs, the answer is usually yes; the bug-reproduction cases that needed replay turn out to be rare in practice. For consumer products with non-technical users, replay is harder to give up — in which case the right move is to stay on Sentry, or move to Highlight, which leans into replay.

  2. Sentry distributed tracing / spans. Netwarden ships request timing on each error (the request that produced it, with timing breadcrumbs), but does not ship full span trees across services. If you used Sentry's Performance product mainly to find slow endpoints, request timing on errors plus a separate APM tool (or your existing logs) covers most of the cases. If you used it to debug cross-service latency in a real microservice mesh, that's an APM product and Netwarden isn't one.

  3. Sentry feature-flag integration. Sentry has a feature-flag product. Netwarden doesn't, and won't — that's a different category. If you used Sentry.setTag("flag.exp1", "B"), the Netwarden equivalent is netwarden.setTag(...), which works for tagging events but doesn't include flag evaluation. The actual flag platform — LaunchDarkly, Statsig, PostHog Flags, OpenFeature — stays where it is.

  4. Sentry profiling. Continuous profiling and flame graphs are a Sentry feature without a Netwarden equivalent. If your debugging workflow depends on flame graphs, Sentry stays. If it doesn't, drop the profilesSampleRate config and don't think about it again.

  5. Sentry alert routing to Slack / PagerDuty / Discord. Netwarden ships email, mobile push, and webhook. We do not ship native Slack or PagerDuty integrations today. The webhook path covers both — point a Netwarden webhook at your Slack incoming-webhook URL or your PagerDuty events API endpoint. It works; it's not native. If your on-call workflow assumes the polished Sentry-Slack integration with rich threaded replies and ack buttons, the webhook is a step down. Plan accordingly.

That's the whole list. Everything else — error capture, breadcrumbs, source maps, release tagging, user context, custom tags, custom contexts, ignore-rules, beforeSend filtering — has a 1:1 equivalent.

What you GAIN by switching

Three things that aren't in Sentry at all:

  • Dependency-update CVE alerts. Your package-lock.json (or pnpm-lock.yaml, bun.lock, requirements.txt, Gemfile.lock, go.sum, Cargo.lock, pom.xml, *.csproj, composer.lock) is read on SDK init and matched daily against OSV.dev advisories across eight ecosystems. When a CVE patch ships for a package in your lockfile, you get an email and a push notification with the fixed version printed inline. None of the other error trackers do this.
  • Fixed pricing. Free, Solo $9, Studio $29, Agency $79. Soft caps, no overage line. The full pricing logic is on the pricing page and the why is in the alternatives post.
  • Self-host on one binary. The same Bun-compiled netwarden binary that runs the host monitor also runs the Apps surface. Bring your own SQLite or Postgres, no docker-compose stack.

If you also use Netwarden for host monitoring, Apps appears as a tab inside the same tenant — same dashboard, same invoice, same alert preferences.

Optional: keep Sentry running in parallel for a week

A safe cutover pattern: install @netwarden/sdk alongside @sentry/browser for a week, initialize both, and capture to both. The two SDKs don't conflict — they hook the same browser events and call separate transport paths. You get parallel data.

import * as Sentry from "@sentry/browser";
import * as netwarden from "@netwarden/sdk";

Sentry.init({ dsn: process.env.SENTRY_DSN });
netwarden.init({ dsn: process.env.NETWARDEN_DSN });

Compare error counts and Issue groupings between the two products for a few days. If they agree (within rounding for sampling), cut Sentry out. If they don't, file a bug — a meaningful disagreement is something we want to know about during alpha. This is the lowest-risk cutover path and the one I'd recommend for any production app with traffic that matters.

Closing

The cutover is short. The biggest variable in the 30-minute estimate is your build pipeline, not the SDK swap itself — if you have a CI step that calls sentry-cli, you'll spend most of the time editing that step.

If you hit something that doesn't translate cleanly, email [email protected]. Alpha-stage SDKs do have rough edges, and a migration report from a production codebase is one of the most useful bug reports we get.

Once the cutover is done, the getting-started doc and the Apps overview doc cover the rest of the platform — alert preferences, dependency-finding routing, source-map troubleshooting.


Keep reading

Get More Monitoring Insights

Subscribe to our weekly newsletter for monitoring tips and industry insights.

Join 2,000+ developers getting weekly monitoring insights

No spam. Unsubscribe anytime.

Share this article

Help others discover simple monitoring

Related Articles

WordPress Monitoring, Honestly: What to Watch and What to Skip

Most WordPress monitoring guides promise the moon — Core Web Vitals, real-user analytics, synthetic browser tests from twenty cities. This one is the honest version: here's what's worth watching, what we actually monitor, and what we don't.

Netwarden Team-May 11

How Netwarden's Security Wedge Works

Most monitoring tools don't surface security signals. Most security tools don't surface monitoring signals. We built one tool that does both — because the people we sell to don't want to pay for two. Here's how the security wedge actually works under the hood.

Netwarden Team-May 11

Error tracking for Vercel apps: errors, dependencies, and analytics in one

If your Next.js app lives on Vercel, error tracking should be five lines plus a build env var. Here's the concrete setup — Edge runtime, instrumentation.ts, source-map upload — for a stack that doesn't bill per event.

Netwarden Team-May 8

Ready for Simple Monitoring?

Stop wrestling with complex monitoring tools. Get started with Netwarden today.

Get Started FreeView Pricing