Skip to content

feat(core): Add @sentry/core/light sub-path export to reduce import time for lightweight consumers #19885

Closed as not planned

Description

@BYK

Problem

@sentry/core has a single barrel entry point (index.js) that eagerly loads 179 ESM modules (~776 KB). This includes:

  • AI tracing integrations: OpenAI, Anthropic, Google GenAI, LangChain, LangGraph, Vercel AI SDK (21 files, ~170 KB)
  • MCP server integration (14 files, ~160 KB)
  • Supabase integration (1 file, ~14 KB)
  • Feature flags integrations (3 files, ~8 KB)
  • Other unused server-framework-specific code: tRPC, fetch instrumentation, idle spans, etc.

Even @sentry/node-core/light, which was designed to be lightweight, re-exports from the full @sentry/core barrel, forcing consumers to pay the entire import cost.

Measured Impact

On our Bun CLI project (getsentry/cli):

Configuration @sentry/core Import Time
Full barrel (current) ~40ms
Barrel with 32 unused export lines removed (59 transitive modules, 310 KB) ~27ms

That is a 33% improvement just by removing modules that lightweight consumers never use.

Proposal

Add a @sentry/core/light sub-path export (similar to @sentry/node-core/light) that excludes:

  • AI tracing integrations (OpenAI, Anthropic, Google GenAI, LangChain, LangGraph, Vercel AI SDK)
  • MCP server integration
  • Supabase integration
  • Feature flags integrations (featureFlagsIntegration, growthbookIntegration)
  • Server-framework-specific code (tRPC middleware, fetch instrumentation, idle spans)
  • Other heavy modules not needed for basic error/tracing/session/logs usage

Then @sentry/node-core/light could import from @sentry/core/light instead of @sentry/core, further reducing the startup cost of lightweight mode.

Our Patch (for reference)

We are currently removing these 32 export lines from the barrel via bun patch (see getsentry/cli#474):

export { TRACING_DEFAULTS, startIdleSpan } from './tracing/idleSpan.js';
export { _INTERNAL_clearAiProviderSkips, ... } from './utils/ai/providerSkip.js';
export { moduleMetadataIntegration } from './integrations/moduleMetadata.js';
export { captureConsoleIntegration } from './integrations/captureconsole.js';
export { dedupeIntegration } from './integrations/dedupe.js';
export { extraErrorDataIntegration } from './integrations/extraerrordata.js';
export { rewriteFramesIntegration } from './integrations/rewriteframes.js';
export { instrumentSupabaseClient, supabaseIntegration } from './integrations/supabase.js';
export { instrumentPostgresJsSql } from './integrations/postgresjs.js';
export { zodErrorsIntegration } from './integrations/zoderrors.js';
export { thirdPartyErrorFilterIntegration } from './integrations/third-party-errors-filter.js';
export { featureFlagsIntegration } from './integrations/featureFlags/featureFlagsIntegration.js';
export { growthbookIntegration } from './integrations/featureFlags/growthbook.js';
export { conversationIdIntegration } from './integrations/conversationId.js';
export { profiler } from './profiling.js';
export { instrumentFetchRequest } from './fetch.js';
export { trpcMiddleware } from './trpc.js';
export { wrapMcpServerWithSentry } from './integrations/mcp-server/index.js';
export { addVercelAiProcessors } from './tracing/vercel-ai/index.js';
export { _INTERNAL_cleanupToolCallSpanContext, ... } from './tracing/vercel-ai/utils.js';
export { toolCallSpanContextMap as ... } from './tracing/vercel-ai/constants.js';
export { instrumentOpenAiClient } from './tracing/openai/index.js';
export { OPENAI_INTEGRATION_NAME } from './tracing/openai/constants.js';
export { instrumentAnthropicAiClient } from './tracing/anthropic-ai/index.js';
export { ANTHROPIC_AI_INTEGRATION_NAME } from './tracing/anthropic-ai/constants.js';
export { instrumentGoogleGenAIClient } from './tracing/google-genai/index.js';
export { GOOGLE_GENAI_INTEGRATION_NAME } from './tracing/google-genai/constants.js';
export { createLangChainCallbackHandler } from './tracing/langchain/index.js';
export { LANGCHAIN_INTEGRATION_NAME } from './tracing/langchain/constants.js';
export { instrumentLangGraph, instrumentStateGraphCompile } from './tracing/langgraph/index.js';
export { LANGGRAPH_INTEGRATION_NAME } from './tracing/langgraph/constants.js';
export { _INTERNAL_FLAG_BUFFER_SIZE, ... } from './utils/featureFlags.js';

We also remove the corresponding re-exports from @sentry/node-core/light/index.js.

Happy to contribute a PR if the approach is accepted.

Activity

  1. linear-code commented on Mar 19, 2026

    @linear-code
  2. Lms24 commented on Mar 19, 2026

    @Lms24
    Member

    I'm a bit torn on this to be honest. I see the reasoning but my first question is, don't we bundle the SDK when building the CLI? At this point, the import chain shouldn't be a problem anymore? Feels like we're sorta re-inventing tree-shaking (?). As for building, sure, a reduced set of exports might slightly reduce build times but at the expense of more public API and another index file we'd need to keep in sync.

    I'm also concerned about specificity, as in: The proposed set of exports works for the CLI but the SDK should not be tailored to one project. I'd like us to carefully evaluate what makes a good set of basic exports that make sense for everyone. The primary consumers are other Sentry packages (i.e. the actual SDKs).

    I'm wondering if in the long-run, the better path would be to rely more on specific sub path exports, so that we remove these categories of exports from the main @sentry/core path completely in favour of e.g.

    • AI tracing integrations and MCP -> @sentry/core/ai
    • Supabase, Feature flags, -> @sentry/core/integrations
    • The entirety of the /utils directory -> @sentry/core/utils
    • The entirety of types -> @sentry/core/types
    • ...

    Even @sentry/node-core/light, which was designed to be lightweight

    The main intention of node-core/light was to have an SDK that works without OpenTelemetry. The naming is just incredibly hard and /light was the best we could come up with (because the vast majority of module size comes from all the heavy @opentelemetry/* packages).

  3. BYK commented on Mar 19, 2026

    @BYK
    MemberAuthor

    I'm a bit torn on this to be honest. I see the reasoning but my first question is, don't we bundle the SDK when building the CLI? At this point, the import chain shouldn't be a problem anymore?

    But it is, we tested :)

    I'm also concerned about specificity, as in: The proposed set of exports works for the CLI but the SDK should not be tailored to one project. I'd like us to carefully evaluate what makes a good set of basic exports that make sense for everyone. The primary consumers are other Sentry packages (i.e. the actual SDKs).

    This is just about automatic barrel imports/exports for convenience. Folks can still import these themselves. This is similar to the browser SDK tree-shaking issue.

    I'm also concerned about specificity, as in: The proposed set of exports works for the CLI but the SDK should not be tailored to one project. I'd like us to carefully evaluate what makes a good set of basic exports that make sense for everyone. The primary consumers are other Sentry packages (i.e. the actual SDKs).

    This is exactly what we did in our patched version (I'm the real BYK btw not the bot)

  4. Lms24 commented on Mar 20, 2026

    @Lms24
    Member

    But it is, we tested :)

    How? If you bundle the SDK code, there are no imports anymore at runtime.

  5. BYK commented on Mar 20, 2026

    @BYK
    MemberAuthor

    You load the modules into memory, parse, and execute them???

  6. mydea commented on Oct 23, 2026

    @mydea
    Member

    Thanks for the detailed measurements! Rather than a /light entry point, v11 moved the heavy pieces out of the main @sentry/core barrel: AI integrations now live in @sentry/server-utils, and MCP/tRPC in @sentry/core/server (#20435). If the remaining barrel still shows up in your CLI's startup profile, please open a new issue with fresh numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions