Skip to content
StackNext
StackNext
Install

Open source · MIT · Contributions welcome

Product / Limitations

What StackNext does not do.

StackNext is a local development tool, not a production APM. These are intentional boundaries, not claims of completeness. Read them before treating a sample, finding or comparison as proof.

Last updated November 10, 2026

Start here

StackNext observes the current in-memory sample and reports evidence from it. It does not have a historical database, a production deployment model or a model of your source code. A missing signal is not proof that a feature is broken, and a finding is not a confirmed root cause.

The canonical boundary list lives in the limitations documentation. This page summarises the limits that matter most when interpreting a sample.

Runtime and framework

  • Node.js runtime only. Edge runtime and middleware running on Edge are not supported.
  • Next.js 15 and 16, App Router only. The Pages Router is not supported. Run stacknext doctor to confirm your local setup.
  • Development use only. There is no multi-user authentication, TLS, clustering or production hardening. Do not expose the collector or dashboard to a network.
  • No browser tracing. Server-side Next.js spans and database events are in scope. Client-side React renders and browser performance are not.
  • No source maps, replay or profiling. Stacks point at server build output. Requests cannot be replayed, and bodies are never captured.
  • OpenTelemetry SDK packages stay on 2.12. StackNext keeps the SDK on the 2.x line while its Node.js floor is 20.9. Upstream marks these packages deprecated in favour of SDK 3, which requires Node.js 22.15 or newer.

Trace coverage

  • Span coverage is limited to documented Next.js telemetry. StackNext does not patch undocumented internals or use NEXT_PRIVATE_* settings.
  • Server Components are not traced individually. Route and render spans from Next.js are captured instead. withStackNextSpan measures only the work you wrap.
  • Server Actions are not automatically identified by name. Successful actions are visible only when wrapped with withStackNextAction; failures may still appear through onRequestError.
  • Custom application spans exist only where a manual helper is used. StackNext does not infer application functions or database drivers automatically.
  • Fetch spans depend on Next.js instrumentation and are filtered when instrumentation.captureFetch is false.
  • NEXT_OTEL_VERBOSE=1 adds documented Next.js span types, but it still does not expose per-component or per-action names. It increases span volume and dev-server work.
  • A trace is only as complete as the spans Next.js sends. Spans that arrive after retention or after a restart may be missing; missing parents are reported, not silently repaired.
  • Error correlation uses the active span when available. Otherwise it falls back to route, method and a 30-second window, so ambiguous matches can remain uncorrelated or link to the wrong request.

Instrumentation coverage

  • Coverage is computed from the current in-memory retention window, not a historical database or build-time analysis. Restarting the collector changes the result.
  • There is no percentage or composite score. Features are independent and workload-dependent; one number would be misleading.
  • observed proves matching evidence was present. not-observed and unknown do not prove a feature is broken; the sample may simply not have exercised it.
  • Configuration flags are intent only. Setting database.drizzle: true does not register the Drizzle logger, and database.prisma: true does not attach the Prisma event handler.
  • The coverage catalog can change between releases as supported Next.js span types change. Treat the current item list and these limitations as part of the result.

Diagnostics

  • Findings are heuristics, not confirmed root causes. possible means the pattern is consistent with a problem; observed means the measurement exists. Neither proves why the app behaves that way.
  • The current sample is the whole input. Findings can appear, disappear or change as telemetry ages out or new requests arrive.
  • The report is capped. diagnostics.maxFindings defaults to 100, and evidence arrays are bounded. A capped report is not a complete inventory.
  • N+1 is a SQL-shape signal. StackNext cannot see the calling code, prove a loop or recover bind parameters, and a batched query can still repeat for unrelated reasons.
  • Slow requests and slow spans are different signals. Slow-span findings use self time and are suppressed when the request already exceeds slowRequestMs. Do not add overlapping span durations together.
  • Detached traces are excluded. Spans without an attributable request root are noted in sample-integrity metadata instead of being guessed into a request.
  • Repeated HTTP is endpoint-shape based. StackNext cannot tell an intentional retry from independent calls or a missing cache.
  • A 5xx status is not a root cause. The app may have returned it intentionally, the error hook may not have run, or the error record may have aged out.
  • No source or SQL execution. StackNext does not read source files, run SQL or EXPLAIN, inspect indexes, replay requests, edit code or provide index advice.

Regression testing

  • Playwright is the only supported runner. The fixture is optional and active only inside stacknext capture. Running playwright test directly does not capture or compare anything.
  • Captured runs require one worker. Parallel correlation is not supported until it is explicitly documented and tested.
  • Correlation is exact or incomplete. A sample is verified only when the collector finds the injected trace and a server span parented to the injected span id. There is no time-window or nearest-request fallback.
  • Scenario identity depends on the explicit stacknext annotation or a stable test id. Changing it creates a new scenario with no baseline.
  • A comparison needs enough verified samples. The default minimum is three per side; failed, skipped or interrupted samples without telemetry block a verdict.
  • Comparisons are deterministic heuristics, not statistics. Medians and explicit thresholds produce improved, regressed, unchanged or inconclusive. StackNext does not compute p-values, confidence intervals or prove causality.
  • unchanged is not proof of no change. improved is not automatically good: fewer spans or queries can mean missing instrumentation or skipped work.
  • Environment mismatches are inconclusive by default. --ignore-environment computes a result with a warning but does not make environments equivalent.
  • Null durations stay unmeasured. Drizzle query durations are null, never zero, and a metric with null evidence is reported as inconclusive.
  • Structural changes are conservative. Changed trace, span or query shapes normally make a scenario inconclusive even when a regression metric is reported.
  • Report-only by default. compare succeeds unless --fail-on regression, --fail-on inconclusive or --fail-on any matches.
  • No browser artifacts. Screenshots, video and Playwright trace archives are never read or stored.
  • Baselines are portable only across matching environments. A baseline captured on another OS, Node.js, Next.js or instrumentation setup is not a valid reference.

Saved snapshots

  • A snapshot is a frozen copy, not live state. It never updates. Do not describe a snapshot finding as current behavior without checking the live sample.
  • Snapshots intentionally exclude diagnostics and coverage. Re-run diagnostics against the live sample if needed.
  • Automatic snapshots are best effort. Exit snapshots need a graceful shutdown and a non-empty sample; error snapshots respect a 60-second cooldown. A crash or full disk can skip a save.
  • Rotation only affects automatic snapshots. snapshots.autoKeep defaults to 10; manual and imported snapshots accumulate until deleted.
  • Oversized snapshots fail. Each is capped at 64 MiB, and StackNext does not truncate silently.
  • Import is not a trust-boundary bypass. Imported exports are re-normalized and re-redacted, and must match the versioned schema.
  • Snapshots are local files. They contain redacted routes, error text, SQL fragments, attributes and timings. Review them before sharing.

Databases

  • Drizzle Logger does not expose query duration. Duration is null, never zero, and the UI and MCP mark it as unmeasured.
  • Drizzle parameters are counted, not captured. This is intentional.
  • Prisma requires event-based query logging. Without log: [{ emit: 'event', level: 'query' }] and instrumentPrismaClient(prisma), no query events arrive.
  • Prisma durations come from Prisma's query event and reflect its reported duration, not a StackNext timer.
  • Query text is redacted, but literal secrets embedded directly in SQL can survive if they do not match a known pattern. Use bind parameters.

Storage and scale

  • Telemetry is in memory only and disappears when stacknext dev exits. export and saved snapshots are the persistence paths.
  • Regression records and snapshots are explicit JSON files under .stacknext. They survive restarts, are never uploaded and are not pruned automatically unless they are automatic snapshots.
  • The store is bounded. When full, the oldest spans, errors and queries are dropped. Drops are counted but not recoverable.
  • Default retention is 10 minutes. Older data is pruned even if capacity is available.
  • There is no sampling UI or tail-based sampling. The transport and collector accept all spans until their bounds are hit.
  • Ingest payloads are capped at 2 MiB, with 500 spans, 25 errors and 100 queries per envelope.
  • SSE is intended for one local dashboard. More than 50 concurrent streams are rejected.
  • Only one collector is supported per app directory. Port fallback tries up to 25 ports after the configured one.

Privacy and security

  • Redaction is pattern-based and best effort, not a formal data-loss prevention system. Review exports and snapshots before sharing them.
  • Any process or agent that can read your user's files can read the bearer token in .stacknext/run.json.
  • The collector uses plain HTTP over loopback, not HTTPS. Host, Origin and Sec-Fetch checks and a CSP reduce browser-based attacks but do not make an untrusted machine safe.
  • MCP data is available to whichever client you connect. That client may log or transmit tool results under its own policy.
  • The dashboard session cookie is HttpOnly and SameSite=Strict but is not marked Secure because the local collector uses HTTP.

Coding agents

  • Client support varies. Prompts, structured content, output schemas and Agent Skills are optional protocol features; a client may call tools without showing prompts or loading the skill.
  • A connected server is not a successful investigation. A model can ignore tools, overstate a fallback correlation or misread an unmeasured duration.
  • Skill discovery is client-specific. Installing the skill does not configure MCP, and configuring MCP does not install the skill.
  • No AI key or hosted model is bundled. The chosen client may require its own account, and its retention and logging policies apply to tool results.
  • Compatibility is tested, not universal. The versions in the agent-testing record are a point-in-time snapshot.

Operations

  • The dashboard is a static build. A source change in packages/dashboard requires a dashboard build before the collector serves it.
  • The CLI requires a dev script in package.json. Custom start commands that do not start Next.js will not produce Next.js spans.
  • CLI commands that attach to a live runtime use .stacknext/run.json. If it is stale, remove it and restart.
  • Captured Playwright runs need a browser installed, for example pnpm exec playwright install chromium.
  • A capture attaches to stacknext dev when it is running, otherwise it starts an ephemeral loopback collector. --attach refuses the fallback.
  • Manual span and action helpers depend on an OpenTelemetry provider. Without registerStackNext() or another provider, they are no-ops.
  • There is no automatic update mechanism, cloud account, hosted dashboard or team sync.