$npx -y skills add getsentry/sentry-for-ai --skill sentry-span-streaming-dartMigrate Dart/Flutter SDK to Sentry span streaming (span-first trace lifecycle). Use when asked to "enable span streaming", "migrate to span streaming", "use traceLifecycle stream", "use Sentry.startSpan", or switch from transaction-based to streamed span delivery in a Dart or Flu
| 1 | > [All Skills](../../SKILL_TREE.md) > [Feature Setup](../sentry-feature-setup/SKILL.md) > Span Streaming (Dart) |
| 2 | |
| 3 | # Sentry Span Streaming Migration (Dart/Flutter) |
| 4 | |
| 5 | Migrate from the default transaction-based trace lifecycle (`SentryTraceLifecycle.static`) to span streaming (`SentryTraceLifecycle.stream`), where spans are sent individually as they complete instead of being batched into a transaction at the end. |
| 6 | |
| 7 | This skill covers the Dart and Flutter SDKs (`sentry`, `sentry_flutter`, and integration packages such as `sentry_dio`, `sentry_sqflite`, `sentry_drift`). For JavaScript, see [Span Streaming (JavaScript)](../sentry-span-streaming-js/SKILL.md). For Python, see [Span Streaming (Python)](../sentry-span-streaming-python/SKILL.md). |
| 8 | |
| 9 | ## Invoke This Skill When |
| 10 | |
| 11 | - User asks to "enable span streaming" or "migrate to span streaming" in a Dart or Flutter project |
| 12 | - User wants to switch from transaction-based to streamed span delivery |
| 13 | - User mentions `traceLifecycle`, `SentryTraceLifecycle.stream`, `Sentry.startSpan`, or `SentrySpanV2` |
| 14 | - User wants lower latency span delivery or per-span processing |
| 15 | |
| 16 | --- |
| 17 | |
| 18 | ## Phase 1: Detect |
| 19 | |
| 20 | ### 1.1 Detect SDK and Version |
| 21 | |
| 22 | ```bash |
| 23 | # Which Sentry packages does the project use? |
| 24 | grep -n "sentry" pubspec.yaml 2>/dev/null |
| 25 | |
| 26 | # Resolved versions — span streaming requires >= 9.19.0 |
| 27 | grep -A8 '^ sentry:' pubspec.lock 2>/dev/null | grep -m1 version |
| 28 | grep -A8 '^ sentry_flutter:' pubspec.lock 2>/dev/null | grep -m1 version |
| 29 | ``` |
| 30 | |
| 31 | Span streaming requires `sentry` / `sentry_flutter` `>=9.19.0`. |
| 32 | |
| 33 | ### 1.2 Find Existing Sentry Config and Tracing Usage |
| 34 | |
| 35 | ```bash |
| 36 | # Find init calls |
| 37 | grep -rn "SentryFlutter\.init\|Sentry\.init" lib/ bin/ test/ --include="*.dart" 2>/dev/null | head -10 |
| 38 | |
| 39 | # Find old transaction API usage (these become no-ops in streaming mode) |
| 40 | grep -rn "startTransaction\|\.startChild(" lib/ bin/ test/ --include="*.dart" 2>/dev/null | head -20 |
| 41 | |
| 42 | # Find callbacks affected by the migration |
| 43 | grep -rn "beforeSendTransaction\|beforeSendSpan\|ignoreSpans" lib/ bin/ test/ --include="*.dart" 2>/dev/null |
| 44 | |
| 45 | # Find untyped span data/tag usage on transactions |
| 46 | grep -rn "\.setData(\|\.setTag(" lib/ bin/ test/ --include="*.dart" 2>/dev/null | head -20 |
| 47 | ``` |
| 48 | |
| 49 | ### 1.3 Classify the Migration Work |
| 50 | |
| 51 | | Finding | Migration Work | |
| 52 | |---|---| |
| 53 | | `Sentry.startTransaction(...)` calls | Replace with `Sentry.startSpan` / `Sentry.startSpanSync` / `Sentry.startInactiveSpan` | |
| 54 | | `span.startChild(...)` calls | Replace with nested `Sentry.startSpan` calls — parenting is automatic via zones | |
| 55 | | `setData` / `setTag` on spans | Replace with typed `span.setAttribute(...)` / `SentryAttribute` | |
| 56 | | `beforeSendTransaction` callback | Never called in streaming mode — migrate logic to `beforeSendSpan` or `ignoreSpans` | |
| 57 | | Existing `beforeSendSpan` / `ignoreSpans` usage | Review against streaming semantics — `beforeSendSpan` is mutation-only, `ignoreSpans` matches names only (see 2.5/2.6) | |
| 58 | | Only auto-instrumentation (no manual spans) | Just enable the option — integrations switch automatically | |
| 59 | |
| 60 | --- |
| 61 | |
| 62 | ## Phase 2: Migrate |
| 63 | |
| 64 | **Prerequisites:** `sentry` / `sentry_flutter` `>=9.19.0` with tracing enabled (`tracesSampleRate` or `tracesSampler` configured). |
| 65 | |
| 66 | ### 2.1 Enable Span Streaming |
| 67 | |
| 68 | Set `traceLifecycle` in the init options. This is the only required config change. |
| 69 | |
| 70 | ```dart |
| 71 | // Flutter |
| 72 | await SentryFlutter.init((options) { |
| 73 | options.dsn = '__DSN__'; |
| 74 | options.tracesSampleRate = 1.0; |
| 75 | options.traceLifecycle = SentryTraceLifecycle.stream; |
| 76 | }, appRunner: () => runApp(const MyApp())); |
| 77 | |
| 78 | // Plain Dart |
| 79 | await Sentry.init((options) { |
| 80 | options.dsn = '__DSN__'; |
| 81 | options.tracesSampleRate = 1.0; |
| 82 | options.traceLifecycle = SentryTraceLifecycle.stream; |
| 83 | }); |
| 84 | ``` |
| 85 | |
| 86 | You can only use one tracing system at a time: |
| 87 | |
| 88 | - In `stream` mode, the transaction APIs (`Sentry.startTransaction`, `ISentrySpan.startChild`) do nothing and log a warning. |
| 89 | - In `static` mode (the default), the new span APIs (`Sentry.startSpan`) do nothing. |
| 90 | - Auto-instrumentations automatically switch to the correct API based on this setting. |
| 91 | |
| 92 | ### 2.2 Replace Transactions with Spans |
| 93 | |
| 94 | `Sentry.startSpan` runs an async callback and ends the span when the returned future completes. Nested calls auto-parent through zones — there is no `startChild` equivalent to migrate to; just nest. |
| 95 | |
| 96 | ```dart |
| 97 | // Before (static mode) |
| 98 | final transaction = Sentry.startTransaction('checkout', 'task'); |
| 99 | try { |
| 100 | final child = transaction.startChild('db.query', description: 'load cart'); |
| 101 | final cart = await loadCart(); |
| 102 | await child.finis |