Skip to content

feat(elysia): Elysia SDK#19509

Draft
logaretm wants to merge 23 commits intodevelopfrom
awad/js-1542-add-elysia-integration
Draft

feat(elysia): Elysia SDK#19509
logaretm wants to merge 23 commits intodevelopfrom
awad/js-1542-add-elysia-integration

Conversation

@logaretm
Copy link
Member

@logaretm logaretm commented Feb 24, 2026

Key Decisions:

  • Built on @sentry/bun since Elysia is Bun-first.
  • We uses Elysia's first-party OTel plugin for lifecycle instrumentation instead of rolling our own.
  • We had to filter out bunServerIntegration to avoid competing root spans, as Elysia creates its own.
  • Error handling: Captures 5xx and <= 299, skips 3xx/4xx. Aligned with Fastify. Overridable via shouldHandleError.
  • Client hooks registered once via module-level guard, safe to call withElysia() multiple times.
  • Elysia produces empty child spans for arrow function handlers. We collect their IDs in spanEnd (still empty at that point) and strip them in beforeSendEvent. Unless the user provides a named function, we will strip them, check the trace below as an example of a named function logRequest vs the stripped event handlers in other life cycle hooks.
CleanShot 2026-03-05 at 15 19 34@2x CleanShot 2026-03-05 at 15 02 12@2x

TODOs:

  • Plugin API to address registration order.
  • Figure out a way to drop the root span or parameterize it.
  • Transform into an SDK

Closes #18956

@linear
Copy link

linear bot commented Feb 24, 2026

JS-1542 Add Elysia

@github-actions
Copy link
Contributor

github-actions bot commented Feb 24, 2026

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 25.63 kB - -
@sentry/browser - with treeshaking flags 24.13 kB - -
@sentry/browser (incl. Tracing) 42.43 kB - -
@sentry/browser (incl. Tracing, Profiling) 47.09 kB - -
@sentry/browser (incl. Tracing, Replay) 81.25 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 70.87 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 85.95 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 98.21 kB - -
@sentry/browser (incl. Feedback) 42.44 kB - -
@sentry/browser (incl. sendFeedback) 30.3 kB - -
@sentry/browser (incl. FeedbackAsync) 35.35 kB - -
@sentry/browser (incl. Metrics) 26.8 kB - -
@sentry/browser (incl. Logs) 26.94 kB - -
@sentry/browser (incl. Metrics & Logs) 27.61 kB - -
@sentry/react 27.38 kB - -
@sentry/react (incl. Tracing) 44.77 kB - -
@sentry/vue 30.08 kB - -
@sentry/vue (incl. Tracing) 44.3 kB - -
@sentry/svelte 25.66 kB - -
CDN Bundle 28.17 kB - -
CDN Bundle (incl. Tracing) 43.26 kB - -
CDN Bundle (incl. Logs, Metrics) 29.01 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 44.1 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 68.09 kB - -
CDN Bundle (incl. Tracing, Replay) 80.14 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 85.65 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 86.53 kB - -
CDN Bundle - uncompressed 82.35 kB - -
CDN Bundle (incl. Tracing) - uncompressed 128.07 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 85.19 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 130.9 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 208.85 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 244.95 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 247.77 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 257.86 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 260.67 kB - -
@sentry/nextjs (client) 47.18 kB - -
@sentry/sveltekit (client) 42.89 kB - -
@sentry/node-core 52.28 kB +0.09% +45 B 🔺
⛔️ @sentry/node (max: 175 kB) 202.87 kB +16.12% +28.16 kB 🔺
⛔️ @sentry/node - without tracing (max: 98 kB) 99.65 kB +2.33% +2.27 kB 🔺
⛔️ @sentry/aws-serverless (max: 114 kB) 119.49 kB +5.57% +6.3 kB 🔺

View base workflow run

@github-actions
Copy link
Contributor

github-actions bot commented Feb 24, 2026

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 11,010 - 8,663 +27%
GET With Sentry 2,019 18% 1,519 +33%
GET With Sentry (error only) 7,551 69% 5,712 +32%
POST Baseline 1,299 - 1,143 +14%
POST With Sentry 630 48% 565 +12%
POST With Sentry (error only) 1,160 89% 1,020 +14%
MYSQL Baseline 3,538 - 3,147 +12%
MYSQL With Sentry 509 14% 383 +33%
MYSQL With Sentry (error only) 2,991 85% 2,587 +16%

View base workflow run

@logaretm logaretm changed the title feat(node-core/bun): Add Elysia Integration feat(elysia): Elysia SDK Mar 5, 2026
logaretm and others added 16 commits March 5, 2026 14:19
Set the transaction name from the parameterized route on the isolation
scope in the onError handler so error events include the correct
transaction name (e.g. `GET /test-exception/:id`).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tests for request metadata on errors, POST body capture, parent-child
spans, and trace propagation. Propagation tests for outgoing fetch are
marked fixme due to Bun's native fetch not emitting undici diagnostics
channels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Capture errors with status >= 500 or <= 299 (unusual status in error
handler). 3xx and 4xx are not captured by default. Adds unit tests for
withElysia and an E2E test for the <= 299 case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add E2E test for thrown string errors (non-Error objects).
Add fixme test documenting that isolation scopes leak between
concurrent requests — setUser/setTag on the isolation scope
is shared across requests since per-request scope forking
is not yet implemented.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add onAfterHandle hook that sets sentry-trace and baggage response
headers, enabling client-side trace continuation from server responses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@logaretm logaretm force-pushed the awad/js-1542-add-elysia-integration branch from 88a46a9 to c6397a8 Compare March 5, 2026 19:20
logaretm and others added 7 commits March 5, 2026 14:24
Replace Object.fromEntries(headers.entries()) with winterCGHeadersToDict
which is compatible with all Headers implementations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refine the logic to filter out empty spans generated for function handlers. This change ensures that spans without a name or attributes do not clutter transactions, while still allowing user-named spans to be displayed correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Elysia

1 participant