Skip to content

feat(server-runtime-injection): Split runtime orchestrion injection into a dedicated package - #23685

Open
mydea wants to merge 7 commits into
developfrom
split/server-runtime-injection
Open

feat(server-runtime-injection): Split runtime orchestrion injection into a dedicated package#23685
mydea wants to merge 7 commits into
developfrom
split/server-runtime-injection

Conversation

@mydea

@mydea mydea commented Aug 27, 2026

Copy link
Copy Markdown
Member

Stacked on #23675 (the detect/warn work) — base this on fix/orchestrion-detect-bundling; rebase onto develop once #23675 merges.

The runtime diagnostics-channel injection (register/hook/import-hook + the vendored transformer chain meriyah/esquery/astring/source-map/tracing-hooks) must stay external when apps bundle their server, while the rest of @sentry/server-utils (barrel + config + bundler plugins) is meant to be bundled. Sharing one package made externalization fiddly (Next.js forwarders, the vite plugin couldn't cleanly separate them). This moves the runtime injection into a new package, @sentry/server-runtime-injection, so "keep this external" is a clean package boundary.

What moves / stays

  • New @sentry/server-runtime-injection: register/hook/import-hook (clean subpaths /register, /hook, /import-hook) + the vendored transformer chain. It depends on @sentry/server-utils and imports SENTRY_INSTRUMENTATIONS from ./orchestrion/configconfig stays put (pure data; resolves from node_modules, one-way dep, no cycle), so @sentry/server-utils remains fully bundleable.
  • @sentry/server-utils: drops the runtime dir/exports and the runtime-only vendored dep (@apm-js-collab/tracing-hooks); keeps the barrel + config + bundler plugins.
  • Bun plugin moved into @sentry/server-utils as ./orchestrion/bun, alongside the vite/rollup/webpack/esbuild plugins; @sentry/bun/plugin now just re-exports it as sentryBunPlugin. This lets config/index.ts drop its bundler re-export (it only existed so @sentry/bun could compose the upstream plugin itself), keeping ./orchestrion/config transformer-free without needing a separate bundler-transforms subpath.

References updated

  • Node SDK (sdk/index.ts + test mock), Deno (import.mjs), the shared --import template + makeOrchestrionLoader guard (one source for every framework's generated hook).
  • Next.js: ORCHESTRION_RUNTIME_EXTERNAL_PACKAGES → the new package; the require-ability check is re-anchored at @sentry/nextjs (so it works under pnpm, where a server-utils-anchored resolver couldn't see the new package); forwarder generation iterates the new package's exports; tests updated.
  • .size-limit.js hook path; the @sentry/server-runtime-injection dep added to node/nextjs/deno/aws-serverless/google-cloud-serverless/astro/tanstackstart-react.
  • Registration: root workspaces, .craft.yml (base tier, after server-utils), CODEOWNERS, the aws-serverless e2e packagesToLink.

Verification

New package builds (config external, transformer vendored, own THIRD-PARTY-LICENSES) and its tests pass; server-utils (353), node (362), bun (50), and the Next.js config tests (122) pass; lint clean across all changed packages. Smoke-tested register in ESM + CJS (healthy → hooks install, no warning), the relocated bun plugin (banner + force-bundle instrumented deps), and confirmed the detection probe still fires on a tree-shaken bundle (warns once, exit 0). size-limit unchanged@sentry/node 119.79 kB, hook entry 79.78 kB, all pass.

Follow-ups

🤖 Generated with Claude Code

Comment thread dev-packages/rollup-utils/npmHelpers.mjs
Comment thread packages/bun/src/plugin.ts
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 28.56 kB -4.27% -1.27 kB 🔽
@sentry/browser - with treeshaking flags 26.92 kB -3.95% -1.11 kB 🔽
@sentry/browser (incl. Tracing) 48.75 kB +3.19% +1.51 kB 🔺
@sentry/browser (incl. Tracing + Span Streaming) 48.76 kB +3.16% +1.49 kB 🔺
@sentry/browser (incl. Tracing, Profiling) 51.68 kB -0.62% -321 B 🔽
@sentry/browser (incl. Tracing, Replay) 88.23 kB +1.89% +1.64 kB 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 77.63 kB +2.14% +1.62 kB 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 92.93 kB +1.81% +1.65 kB 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 105.85 kB +1.83% +1.9 kB 🔺
@sentry/browser (incl. Feedback) 46.05 kB -2.31% -1.09 kB 🔽
@sentry/browser (incl. sendFeedback) 33.62 kB -3.02% -1.04 kB 🔽
@sentry/browser (incl. FeedbackAsync) 38.73 kB -2.64% -1.05 kB 🔽
@sentry/browser (incl. Metrics) 29.51 kB -4.53% -1.4 kB 🔽
@sentry/browser (incl. Logs) 29.8 kB -4.32% -1.34 kB 🔽
@sentry/browser (incl. Metrics & Logs) 30.43 kB -4.35% -1.38 kB 🔽
@sentry/react 30.3 kB -4.19% -1.32 kB 🔽
@sentry/react (incl. Tracing) 50.94 kB +2.9% +1.43 kB 🔺
@sentry/vue 35.73 kB +2.31% +806 B 🔺
@sentry/vue (incl. Tracing) 51.02 kB +3.61% +1.77 kB 🔺
@sentry/svelte 28.59 kB -4.25% -1.27 kB 🔽
CDN Bundle 30.35 kB -4.79% -1.52 kB 🔽
CDN Bundle (incl. Tracing) 49.38 kB +3.88% +1.84 kB 🔺
CDN Bundle (incl. Logs, Metrics) 32.58 kB -2.5% -834 B 🔽
CDN Bundle (incl. Tracing, Logs, Metrics) 51.25 kB +4.72% +2.31 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 73.17 kB +0.59% +425 B 🔺
CDN Bundle (incl. Tracing, Replay) 86.86 kB +1.97% +1.68 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 88.73 kB +2.58% +2.23 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 92.8 kB +1.97% +1.79 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 94.64 kB +2.53% +2.33 kB 🔺
CDN Bundle - uncompressed 89.95 kB -4.94% -4.67 kB 🔽
CDN Bundle (incl. Tracing) - uncompressed 147.2 kB +3.58% +5.08 kB 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 96.24 kB -3.02% -3 kB 🔽
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 152.89 kB +4.65% +6.79 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 225.41 kB +0.66% +1.47 kB 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 266.69 kB +2.04% +5.32 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 272.37 kB +2.65% +7.03 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 280.4 kB +1.94% +5.32 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 286.06 kB +2.52% +7.03 kB 🔺
@sentry/nextjs (client) 53.56 kB +2.84% +1.48 kB 🔺
@sentry/sveltekit (client) 49.19 kB +3.11% +1.48 kB 🔺
@sentry/core/server 65.67 kB +0.22% +144 B 🔺
@sentry/core/browser 51.86 kB -0.04% -20 B 🔽
@sentry/node 123.76 kB +2.94% +3.52 kB 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 81.6 kB added added
@sentry/node - without tracing 88.02 kB +5.18% +4.33 kB 🔺
@sentry/aws-serverless 96.42 kB +4.4% +4.06 kB 🔺
@sentry/cloudflare (withSentry) - minified 201.04 kB -8.06% -17.61 kB 🔽
@sentry/cloudflare (withSentry) 500.26 kB -7.17% -38.59 kB 🔽
@sentry/browser - with treeshaking flags tracing without tracing 26.82 kB added added
@sentry/node - without channel injection 103.18 kB added added

View base workflow run

@mydea
mydea marked this pull request as ready for review August 27, 2026 14:28
@mydea
mydea requested review from a team as code owners August 27, 2026 14:28
@mydea
mydea requested review from JPeer264, chargome, isaacs and s1gr1d and removed request for a team August 27, 2026 14:28
@mydea
mydea force-pushed the split/server-runtime-injection branch 2 times, most recently from 24c382c to 2a2a5e3 Compare August 28, 2026 09:50
Comment thread packages/server-runtime-injection/package.json

@isaacs isaacs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's definitely more opportunities for clean-up and a few things that should probably be addressed to avoid excess disk usage, but splitting these parts into a separate package is exactly the right approach, imo 👍

Comment thread packages/server-runtime-injection/package.json Outdated
Comment thread packages/server-runtime-injection/package.json
@@ -1,20 +1,15 @@
import { builtinModules } from 'node:module';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rollup changes here, and splitting into two packages, results in getting two copies of @apm-js-collab/code-transformer. We can avoid that by re-exporting the transformer from server-utils, so that it's only written to disk once, and save 6.69MB of install space on disk. (Not bundle size, just disk install size and file count.)

Here's what that could look like:
https://gist.github.com/isaacs/6162f2c166207d564f962ba5c581d1f4

I'm not necessarily married to that approach, definitely adds some redirection complexity, but it is kind of a lot of extra install weight for cf users otherwise.

* build-time snippet's `@sentry/server-utils` import is handled separately by the code-transform.
*/
export const ORCHESTRION_RUNTIME_EXTERNAL_PACKAGES = ['@sentry/server-utils'];
export const ORCHESTRION_RUNTIME_EXTERNAL_PACKAGES = ['@sentry/server-runtime-injection'];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why this is changing, but it does have one interesting ramification.

The orchestrion config now gets loaded twice; once from the server chunk, and once from node_modules via the external register.js in the new package. It's pure data, and guaranteed to be identical, so there's no correctness problem today, but the minute anything stateful gets in there, it's going to be an issue. I'm not sure the best fix there, but that does feel a bit brittle.

Comment thread packages/server-runtime-injection/test/register.test.ts
Comment thread packages/server-runtime-injection/vite.config.ts
* so `bundler` is set (to an empty `Set`) from boot, which gates the SDK's channel-integration setup
* at `init()`.
*/
export function sentryOrchestrionPlugin(): UnknownPlugin {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little bit weird that this method doesn't take a PluginOptions option, since it's siblings all do. Maybe it should take a PluginOptions argument, and at least respect buildTimeInstrumentation: false?

Comment thread packages/server-utils/src/orchestrion/bundler/bun.ts Outdated
Comment thread packages/nextjs/scripts/buildRollup.ts
Base automatically changed from fix/orchestrion-detect-bundling to develop August 31, 2026 13:58
@mydea
mydea force-pushed the split/server-runtime-injection branch from 2a2a5e3 to 082ec3f Compare August 31, 2026 13:58
Comment thread packages/server-runtime-injection/package.json Outdated
mydea and others added 4 commits August 31, 2026 16:06
…nto a dedicated package

The runtime diagnostics-channel injection (`register`/`hook`/`import-hook` + the
vendored transformer chain meriyah/esquery/astring/source-map/tracing-hooks) must
stay EXTERNAL when apps bundle their server, while the rest of `@sentry/server-utils`
(barrel + config + bundler plugins) is meant to be bundled. Sharing one package made
externalization fiddly. This moves the runtime injection into a new package,
`@sentry/server-runtime-injection`, so "keep this external" is a clean package boundary.

- New package holds `register`/`hook`/`import-hook` (subpaths `/register`, `/hook`,
  `/import-hook`) and vendors the transformer chain; it depends on `@sentry/server-utils`
  and imports `SENTRY_INSTRUMENTATIONS` from `./orchestrion/config` (config stays put).
- `@sentry/server-utils` drops the runtime dir/exports and the runtime-only vendored deps;
  the lone `config/index.ts` bundler re-export moves to a new `./orchestrion/bundler-transforms`
  subpath so importing config stays transformer-free (bun updated).
- References updated: node SDK + test mock, deno import, the shared `--import` template +
  `makeOrchestrionLoader` guard, Next.js externalization (`ORCHESTRION_RUNTIME_EXTERNAL_PACKAGES`,
  nextjs-anchored require-ability check, forwarder generation) + tests, `.size-limit.js`.
- Dep added to runtime-injection consumers (node, nextjs, deno, aws/gcp-serverless, astro,
  tanstackstart-react); package registered in workspaces, `.craft.yml`, CODEOWNERS, aws e2e.

Stacked on the detect/warn PR (#23675).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-plugins dependency

`@sentry/bun/plugin` now only re-exports from `@sentry/server-utils/orchestrion/bun`
(which vendors the transformer), so the direct import is gone. Remove the leftover
runtime dependency so installs don't pull an unused package.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mydea
mydea force-pushed the split/server-runtime-injection branch from 082ec3f to 24e43de Compare August 31, 2026 14:06
Comment thread packages/server-runtime-injection/src/register.ts
Comment thread packages/server-runtime-injection/src/register.ts
Comment thread packages/server-runtime-injection/test/register.test.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 043aca6. Configure here.

// Bun's builder to its `setup`.
const transformer = codeTransformer(
orchestrionTransformOptions(options, { injectDiagnostics: false }),
) as unknown as {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bun skips custom instrumented packages

Medium Severity

The Bun plugin now accepts extra instrumentations and forwards them to the transformer, but withoutInstrumentedExternals and the blanket-external warning still use the default INSTRUMENTED_MODULE_NAMES. Custom packages left in external never pass through onLoad, and Bun has no runtime fallback, so those libraries load uninstrumented.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 043aca6. Configure here.

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.

2 participants