Skip to content

feat(core): split exports by browser/server for bundle size#20435

Open
isaacs wants to merge 3 commits intodevelopfrom
isaacschlueter/split-server-browser-core-exports
Open

feat(core): split exports by browser/server for bundle size#20435
isaacs wants to merge 3 commits intodevelopfrom
isaacschlueter/split-server-browser-core-exports

Conversation

@isaacs
Copy link
Copy Markdown
Member

@isaacs isaacs commented Apr 21, 2026

Note: stacked atop #20393, only the top commit needs review. Land that before this one.

Split the exports from @sentry/core into three options:

  • @sentry/core, the default (unchanged)
  • @sentry/core/browser, containing only shared and browser-specific
    functionality, nothing server-specific.
  • @sentry/core/server, containing only shared and server-specific
    functionality, nothing browser-specific.

This allows us to make the bundle sizes quite a bit smaller in our
browser SDKs where this is important, while adding more functionality to
our server-specific SDKs, in @sentry/core where they can be easily
shared across runtimes.

fix: #20434
fix: JS-2243

@linear-code
Copy link
Copy Markdown

linear-code Bot commented Apr 21, 2026

@isaacs isaacs force-pushed the isaacschlueter/split-server-browser-core-exports branch 6 times, most recently from 143a2a5 to 1494709 Compare April 22, 2026 01:45
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 25.88 kB -0.01% -1 B 🔽
@sentry/browser - with treeshaking flags 24.35 kB - -
@sentry/browser (incl. Tracing) 43.8 kB -0.01% -1 B 🔽
@sentry/browser (incl. Tracing + Span Streaming) 45.5 kB - -
@sentry/browser (incl. Tracing, Profiling) 48.73 kB - -
@sentry/browser (incl. Tracing, Replay) 82.98 kB -0.01% -1 B 🔽
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 72.5 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 87.67 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 99.93 kB -0.01% -1 B 🔽
@sentry/browser (incl. Feedback) 42.7 kB - -
@sentry/browser (incl. sendFeedback) 30.55 kB -0.01% -1 B 🔽
@sentry/browser (incl. FeedbackAsync) 35.55 kB -0.01% -1 B 🔽
@sentry/browser (incl. Metrics) 27.16 kB - -
@sentry/browser (incl. Logs) 27.29 kB -0.01% -1 B 🔽
@sentry/browser (incl. Metrics & Logs) 27.98 kB - -
@sentry/react 27.62 kB - -
@sentry/react (incl. Tracing) 46.05 kB - -
@sentry/vue 30.71 kB - -
@sentry/vue (incl. Tracing) 45.62 kB - -
@sentry/svelte 25.89 kB - -
CDN Bundle 28.58 kB +0.03% +8 B 🔺
CDN Bundle (incl. Tracing) 46.08 kB +0.01% +2 B 🔺
CDN Bundle (incl. Logs, Metrics) 29.95 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 47.11 kB -0.02% -6 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) 68.92 kB -0.01% -4 B 🔽
CDN Bundle (incl. Tracing, Replay) 83.14 kB +0.01% +2 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 84.17 kB +0.01% +1 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 88.62 kB +0.02% +10 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 89.69 kB -0.01% -2 B 🔽
CDN Bundle - uncompressed 83.59 kB - -
CDN Bundle (incl. Tracing) - uncompressed 137.62 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 87.73 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 141.03 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 211.31 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 255.06 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 258.46 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 267.97 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 271.36 kB - -
@sentry/nextjs (client) 48.58 kB - -
@sentry/sveltekit (client) 44.22 kB - -
@sentry/node-core 59.02 kB +1.16% +676 B 🔺
@sentry/node 168.01 kB -4.35% -7.64 kB 🔽
@sentry/node - without tracing 72.06 kB -26.69% -26.23 kB 🔽
@sentry/aws-serverless 107.63 kB -6.68% -7.7 kB 🔽

View base workflow run

@isaacs isaacs force-pushed the isaacschlueter/split-server-browser-core-exports branch 5 times, most recently from d5dddbf to 8eba1e9 Compare April 22, 2026 18:26
@isaacs isaacs marked this pull request as ready for review April 22, 2026 18:26
Comment thread dev-packages/rollup-utils/utils.mjs Outdated
@isaacs isaacs force-pushed the isaacschlueter/split-server-browser-core-exports branch from 8eba1e9 to 8ea4f5c Compare April 22, 2026 18:50
Comment thread dev-packages/rollup-utils/npmHelpers.mjs
@isaacs isaacs force-pushed the isaacschlueter/split-server-browser-core-exports branch from 8ea4f5c to 787f44b Compare April 22, 2026 19:19
@isaacs isaacs enabled auto-merge (rebase) April 22, 2026 19:19
@isaacs isaacs disabled auto-merge April 22, 2026 19:19
isaacs added a commit that referenced this pull request Apr 22, 2026
Split the exports from `@sentry/core` into three options:

- `@sentry/core`, the default (unchanged)
- `@sentry/core/browser`, containing _only_ shared and browser-specific
  functionality, nothing server-specific.
- `@sentry/core/server`, containing _only_ shared and server-specific
  functionality, nothing browser-specific.

This should allow us to make the bundle sizes quite a bit smaller in our
browser SDKs where this is important, while adding more functionality to
our server-specific SDKs, in `@sentry/core` where they can be easily
shared across runtimes.

Integration may require updating our `tsconfig` settings so that tsc
knows it is allowed to look on `package.json` exports.

fix: #20434
fix: JS-2243
@isaacs isaacs force-pushed the isaacschlueter/split-server-browser-core-exports branch from 787f44b to 7076f7c Compare April 22, 2026 19:20
Comment thread packages/core/src/shared-exports.ts
Comment thread packages/core/src/integrations/http/client-subscriptions.ts
@isaacs isaacs requested review from mydea and timfish April 23, 2026 14:24
isaacs added 2 commits April 23, 2026 07:28
This was implemented for the portable Express integration, but others
will need the same functionality, so make it a reusable util.
Refactor the `node:http` outgoing request instrumentation so that it can
be applied to non-Node.js environments by patching the http module.

Also, refactor so that the diagnostics_channel and monkeypatching paths
can share code, and so that light and normal node-core instrumentations
can share more of the functionality as well.

To facilitate this, some portable minimal types are vendored in from the
`node:http` module.
isaacs added a commit that referenced this pull request Apr 23, 2026
Split the exports from `@sentry/core` into three options:

- `@sentry/core`, the default (unchanged)
- `@sentry/core/browser`, containing _only_ shared and browser-specific
  functionality, nothing server-specific.
- `@sentry/core/server`, containing _only_ shared and server-specific
  functionality, nothing browser-specific.

This should allow us to make the bundle sizes quite a bit smaller in our
browser SDKs where this is important, while adding more functionality to
our server-specific SDKs, in `@sentry/core` where they can be easily
shared across runtimes.

Integration may require updating our `tsconfig` settings so that tsc
knows it is allowed to look on `package.json` exports.

fix: #20434
fix: JS-2243
@isaacs isaacs force-pushed the isaacschlueter/split-server-browser-core-exports branch from 7076f7c to e2cf052 Compare April 23, 2026 14:34
Split the exports from `@sentry/core` into three options:

- `@sentry/core`, the default (unchanged)
- `@sentry/core/browser`, containing _only_ shared and browser-specific
  functionality, nothing server-specific.
- `@sentry/core/server`, containing _only_ shared and server-specific
  functionality, nothing browser-specific.

This should allow us to make the bundle sizes quite a bit smaller in our
browser SDKs where this is important, while adding more functionality to
our server-specific SDKs, in `@sentry/core` where they can be easily
shared across runtimes.

Integration may require updating our `tsconfig` settings so that tsc
knows it is allowed to look on `package.json` exports.

fix: #20434
fix: JS-2243
@isaacs isaacs force-pushed the isaacschlueter/split-server-browser-core-exports branch from e2cf052 to 67bf5c4 Compare April 23, 2026 14:41
Comment on lines +242 to 245
new InstrumentationNodeModuleDefinition('http', ['*'], wrapHttp),
new InstrumentationNodeModuleDefinition('https', ['*'], wrapHttps),
];
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The SentryHttpInstrumentation no longer provides an unwrap function, meaning diagnostic channel subscriptions are not cleaned up when the instrumentation is disabled via disable().
Severity: LOW

Suggested Fix

Reintroduce the unwrap callback as the fourth parameter to the InstrumentationNodeModuleDefinition constructor. Inside this callback, call unsubscribe() for all diagnostic channels that were subscribed to in the init function, mirroring the cleanup logic from the previous version of the code.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location:
packages/node-core/src/integrations/http/SentryHttpInstrumentation.ts#L242-L245

Potential issue: The refactored `SentryHttpInstrumentation` omits the `unwrap` callback
when defining the instrumentation. Previously, this callback was used to `unsubscribe()`
from diagnostic channels like `HTTP_ON_CLIENT_REQUEST`. Without this cleanup logic, if
`instrumentation.disable()` is ever called, the subscriptions will persist. This causes
handlers to continue firing, leading to the creation of breadcrumbs and spans even after
the instrumentation is supposedly disabled. This is a functional regression from the
previous implementation which correctly managed the subscription lifecycle.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

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 2 potential issues.

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 67bf5c4. Configure here.

// Skip if tracing is suppressed (e.g., inside Sentry.suppressTracing())
if (getCurrentScope().getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] === true) {
return;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suppressTracing skips breadcrumbs and trace propagation entirely

Medium Severity

The SUPPRESS_TRACING_KEY check on the current scope causes the entire onHttpClientRequestCreated handler to return early, skipping not just span creation but also breadcrumbs and trace propagation header injection. The documented behavior of suppressTracing is "ensuring no spans are generated inside of it," but this implementation also suppresses breadcrumbs for HTTP requests made within suppressTracing() callbacks. While suppressing everything is correct for Sentry's own internal outgoing requests, user-facing suppressTracing() usage would unexpectedly lose HTTP breadcrumbs.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 67bf5c4. Configure here.

return {
[HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated,
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing unit tests for new HTTP instrumentation code

Low Severity

This feat PR introduces substantial new production code in packages/core/src/integrations/http/ (client-patch, client-subscriptions, get-outgoing-span-data, inject-trace-propagation-headers, merge-baggage, add-outgoing-request-breadcrumb) but does not include any unit or integration tests specifically covering this new HTTP instrumentation logic. Existing E2E tests were updated to match new assertion values, but the new code paths (patching, breadcrumb creation, trace injection, error handling) lack dedicated test coverage. Per the review rules, feat PRs are expected to include at least one integration or E2E test for new behavior.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 67bf5c4. Configure here.

Copy link
Copy Markdown
Collaborator

@timfish timfish left a comment

Choose a reason for hiding this comment

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

I looked through most of the changed files.

I guess this doesn't deprecate the old root exports yet?

expect.objectContaining({
data: expect.objectContaining({
'sentry.op': 'http.client',
'sentry.origin': 'auto.http.otel.http',
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.

these seem like unrelated changes, a different PR leaking into this? 😅

"include": ["src/**/*"],

"compilerOptions": {
"module": "esnext",
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.

is this related to this change/required here?

"include": ["src/**/*", "test/loader.js"],

"compilerOptions": {
"module": "esnext",
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.

is this required for this change here?


const getExpressExport = (express: ExpressModuleExport): ExpressExport =>
hasDefaultProp(express) ? express.default : (express as ExpressExport);
import { getDefaultExport } from '../../utils/get-default-export';
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.

also likely leaked in from another PR?

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.

Split @sentry/core exports up, adding ./server and ./browser exports

3 participants