Skip to content

✨ Add @datadog/browser-remote-config standalone package and @datadog/browser-sdk-endpoint bundle generator#4331

Draft
mormubis wants to merge 11 commits intoadlrb/ssi-remote-configfrom
adlrb/ssi-endpoint-2
Draft

✨ Add @datadog/browser-remote-config standalone package and @datadog/browser-sdk-endpoint bundle generator#4331
mormubis wants to merge 11 commits intoadlrb/ssi-remote-configfrom
adlrb/ssi-endpoint-2

Conversation

@mormubis
Copy link
Contributor

Motivation

Right now the only way to use remote configuration with the RUM SDK is to pass `remoteConfigurationId` to `DD_RUM.init()`, which triggers a fetch to the RC endpoint at page load. This PR is the foundation for SSI (Server-Side Injection): pre-fetch the RC on the server, generate a self-contained bundle with the SDK and config embedded, serve it as a single `<script>` tag. No RC fetch at page load, no `init()` call needed in app code.

Changes

Two packages:

`@datadog/browser-remote-config` extracts the RC logic into a standalone package. The main addition is a `contextItemHandler` strategy on `resolveDynamicValues` that controls how `ContextItem[]` arrays (the `user` and `context` fields in the RC schema) get resolved. The browser entry point uses getter properties that evaluate against live browser APIs at read time. The Node entry point serializes them as inline JS expressions instead (`__dd_getJs('window.user')`) for embedding in generated bundles.

`@datadog/browser-sdk-endpoint` is a Node.js package that fetches the RC config, runs the code-gen path to turn `DynamicOption` descriptors into inline expressions, downloads the SDK from CDN, and assembles a self-contained IIFE. The `generateBundle` API is designed to sit behind an Express endpoint with per-config caching.

The `contextItemHandler` strategy is the architectural backbone. The browser handler returns a plain object via getters. The Node handler returns a `CodeExpression` (a branded marker type) that tells `serializeConfigToJs` to inline the string as raw JS rather than JSON-encode it. That distinction is what lets the same config tree produce either a live-resolved object in the browser or a JS object literal with embedded expressions in a bundle.

One non-obvious thing worth calling out: `nodeContextItemHandler` receives a `resolve` callback from `resolveDynamicValues`, but calling `resolve(dynamicOption)` in Node context would try to run the live browser resolvers (`window.*`, `getCookie`) and crash. The handler ignores `_resolve` entirely and calls `serializeDynamicValueToJs` directly. Safe because `ContextItem.value` is always a `DynamicOption`.

Test instructions

  1. `yarn test:unit --spec packages/remote-config/src/remoteConfiguration.spec.ts` (46 tests)
  2. `yarn test:unit --spec packages/remote-config/src/nodeResolution.spec.ts` (18 tests)
  3. `node --test packages/endpoint/src/bundleGenerator.spec.ts` (10 tests)

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change. (endpoint package needs a more involved test setup, leaving for follow-up)
  • Updated documentation and/or relevant AGENTS.md file

@cit-pr-commenter-54b7da
Copy link

cit-pr-commenter-54b7da bot commented Mar 13, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum N/A 175.10 KiB N/A N/A N/A
Rum Profiler N/A 6.16 KiB N/A N/A N/A
Rum Recorder N/A 27.46 KiB N/A N/A N/A
Logs N/A 56.80 KiB N/A N/A N/A
Rum Slim N/A 130.74 KiB N/A N/A N/A
Worker N/A 23.63 KiB N/A N/A N/A
🚀 CPU Performance
Action Name Base CPU Time (ms) Local CPU Time (ms) 𝚫%
RUM - add global context 0.005 0.0053 +6.00%
RUM - add action 0.014 0.0181 +29.29%
RUM - add error 0.0134 0.0233 +73.88%
RUM - add timing 0.0035 0.0047 +34.29%
RUM - start view 0.0164 0.0222 +35.37%
RUM - start/stop session replay recording 0.001 0.0014 +40.00%
Logs - log message 0.0165 0.0329 +99.39%
🧠 Memory Performance
Action Name Base Memory Consumption Local Memory Consumption 𝚫
addglobalcontext N/A 26.15 KiB N/A
addaction N/A 52.46 KiB N/A
addtiming N/A 26.52 KiB N/A
adderror N/A 56.78 KiB N/A
startstopsessionreplayrecording N/A 25.48 KiB N/A
startview N/A 466.47 KiB N/A
logmessage N/A 44.43 KiB N/A

🔗 RealWorld

@datadog-datadog-prod-us1-2
Copy link

datadog-datadog-prod-us1-2 bot commented Mar 13, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 74.19%
Overall Coverage: 77.20% (-0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: ecaf9de | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@mormubis mormubis changed the base branch from main to adlrb/ssi-remote-config March 13, 2026 15:25
@mormubis mormubis force-pushed the adlrb/ssi-remote-config branch from c8d543d to bf0351d Compare March 13, 2026 15:32
@mormubis mormubis force-pushed the adlrb/ssi-endpoint-2 branch from d7b8712 to 9de7558 Compare March 13, 2026 15:33
@mormubis mormubis force-pushed the adlrb/ssi-remote-config branch from bf0351d to 9b45817 Compare March 13, 2026 15:35
@mormubis mormubis force-pushed the adlrb/ssi-endpoint-2 branch 4 times, most recently from 9cdef32 to 1c044a4 Compare March 13, 2026 15:55
@mormubis mormubis force-pushed the adlrb/ssi-endpoint-2 branch from 5ec768c to ecaf9de Compare March 17, 2026 14:52
@mormubis mormubis force-pushed the adlrb/ssi-remote-config branch from 62b7c0b to adbf904 Compare March 17, 2026 14:52
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.

1 participant