Contents
- 🚨 Breaking Changes
- Node 22 is now the minimum supported Node.js version (#27116)
- Container runtime instantiation now requires
navigatorto be defined in the runtime environment (#27010)
- ✨ New Features
- Add SchemaFactoryAlpha.stagedOptionalRecursive for recursive staged-optional fields (#27042)
- 🌳 SharedTree DDS Changes
- Fixed incremental summary bug in SharedTree that may cause repeated summary failures eventually leading to document corruption (#26990)
- ⚠️ Deprecations
- Deprecate ITelemetryLoggerExt methods and related types (#26912)
- Legacy API Changes
- Remove IIdCompressorCore from legacy API surface (#27146)
🚨 Breaking Changes
Node 22 is now the minimum supported Node.js version (#27116)
All Fluid Framework client packages now require Node.js 22 or later. This aligns with the standing Node upgrade policy as Node 20 reaches end-of-life on April 30, 2026.
Change details
Commit: e8214d2
Affected packages:
- @fluid-example/table-document
- @fluid-experimental/attributor
- @fluid-experimental/data-object-base
- @fluid-experimental/data-objects
- @fluid-experimental/dds-interceptions
- @fluid-experimental/ink
- @fluid-experimental/last-edited
- @fluid-experimental/odsp-end-to-end-tests
- @fluid-experimental/oldest-client-observer
- @fluid-experimental/ot
- @fluid-experimental/pact-map
- @fluid-experimental/property-changeset
- @fluid-experimental/property-common
- @fluid-experimental/property-dds
- @fluid-experimental/property-properties
- @fluid-experimental/sequence-deprecated
- @fluid-experimental/sharejs-json1
- @fluid-experimental/tree
- @fluid-internal/client-utils
- @fluid-internal/platform-dependent
- @fluid-internal/presence-definitions
- @fluid-internal/presence-runtime
- @fluid-internal/replay-tool
- @fluid-private/test-dds-utils
- @fluid-private/test-loader-utils
- @fluid-tools/fetch-tool
- @fluidframework/agent-scheduler
- @fluidframework/app-insights-logger
- @fluidframework/aqueduct
- @fluidframework/azure-client
- @fluidframework/azure-end-to-end-tests
- @fluidframework/cell
- @fluidframework/container-definitions
- @fluidframework/container-loader
- @fluidframework/container-runtime
- @fluidframework/container-runtime-definitions
- @fluidframework/core-interfaces
- @fluidframework/core-utils
- @fluidframework/counter
- @fluidframework/datastore
- @fluidframework/datastore-definitions
- @fluidframework/debugger
- @fluidframework/devtools
- @fluidframework/devtools-core
- @fluidframework/driver-base
- @fluidframework/driver-definitions
- @fluidframework/driver-utils
- @fluidframework/driver-web-cache
- @fluidframework/file-driver
- @fluidframework/fluid-runner
- @fluidframework/fluid-static
- @fluidframework/fluid-telemetry
- @fluidframework/id-compressor
- @fluidframework/legacy-dds
- @fluidframework/local-driver
- @fluidframework/map
- @fluidframework/matrix
- @fluidframework/merge-tree
- @fluidframework/odsp-client
- @fluidframework/odsp-doclib-utils
- @fluidframework/odsp-driver
- @fluidframework/odsp-driver-definitions
- @fluidframework/odsp-urlresolver
- @fluidframework/ordered-collection
- @fluidframework/presence
- @fluidframework/quill-react
- @fluidframework/react
- @fluidframework/register-collection
- @fluidframework/replay-driver
- @fluidframework/request-handler
- @fluidframework/routerlicious-driver
- @fluidframework/routerlicious-urlresolver
- @fluidframework/runtime-definitions
- @fluidframework/runtime-utils
- @fluidframework/sequence
- @fluidframework/shared-object-base
- @fluidframework/shared-summary-block
- @fluidframework/synthesize
- @fluidframework/task-manager
- @fluidframework/telemetry-utils
- @fluidframework/test-runtime-utils
- @fluidframework/test-utils
- @fluidframework/tinylicious-client
- @fluidframework/tinylicious-driver
- @fluidframework/tool-utils
- @fluidframework/tree
- @fluidframework/tree-agent
- @fluidframework/tree-agent-langchain
- @fluidframework/tree-agent-ses
- @fluidframework/type-factory
- @fluidframework/undo-redo
- fluid-framework
⬆️ Table of contents
Container runtime instantiation now requires navigator to be defined in the runtime environment (#27010)
The internal getDeviceSpec() function, which is called during container runtime instantiation to report hardware telemetry, no longer guards against navigator being null or undefined. This means loading a container runtime requires either a browser environment or Node 22+, both of which provide a built-in navigator global. Environments that do not provide navigator (e.g., older versions of Node.js) will encounter a runtime error when instantiating the container runtime.
This requirement aligns with the recent migration of the repo to Node 22 per our standing Node upgrade policy. Node 20 reaches end-of-life on April 30, 2026.
Change details
Commit: 936562b
Affected packages:
- @fluidframework/container-runtime
⬆️ Table of contents
✨ New Features
Add SchemaFactoryAlpha.stagedOptionalRecursive for recursive staged-optional fields (#27042)
SchemaFactoryAlpha.stagedOptionalRecursive(T) is the recursive-type variant of stagedOptional (released in 2.93.0). Use it for schemas whose types are recursive - the relaxed type constraints work around TypeScript's limitations with recursive schema definitions. Pair it with ValidateRecursiveSchema for improved type safety.
Example:
const sf = new SchemaFactoryAlpha("my-app");
class TreeNode extends sf.objectRecursiveAlpha("TreeNode", {
value: sf.number,
child: sf.stagedOptionalRecursive([() => TreeNode]),
}) {}
type _check = ValidateRecursiveSchema<typeof TreeNode>;See stagedOptional for the migration pattern (required to stagedOptional to optional).
Change details
Commit: a6e084e
Affected packages:
- @fluidframework/tree
⬆️ Table of contents
🌳 SharedTree DDS Changes
Fixed incremental summary bug in SharedTree that may cause repeated summary failures eventually leading to document corruption (#26990)
Incremental summary for SharedTree is off by default. This bug only affects applications that have explicitly enabled incremental summarization.
Affected configurations
A session could be affected if all the following were true:
- Incremental summarization was enabled (opt-in feature, off by default).
- The SharedTree schema had incremental fields nested at least 2 levels deep. For example, a map field marked with
incrementalSummaryHintthat contains objects which themselves have a map field also marked withincrementalSummaryHint. - The document was summarized multiple times, with the outer incremental field changing in at least one summary while the inner incremental field remained unchanged.
Symptoms
Summaries would fail. Depending on the storage service, the error may appear as:
TypeError: Cannot read properties of undefined (reading 'trees')(for example, when using SharePoint storage)
Repeated summary failures can cause a session to accumulate ops without a summary. Once the limit of ops without a summary is reached (~10k), further ops will be rejected, making the document read-only for that session.
Mitigation and recovery
- If a session is already affected, turning off incremental summarization will allow summaries to succeed again.
- Upgrade to this version to prevent further summary failures.
Change details
Commit: 1514c31
Affected packages:
- @fluidframework/tree
⬆️ Table of contents
⚠️ Deprecations
Deprecate ITelemetryLoggerExt methods and related types (#26912)
ITelemetryLoggerExt is only for internal Fluid Framework use. The following deprecations help formalize that. See issue #26910 for details.
| API | Kind | Package Export |
|---|---|---|
TelemetryEventCategory
| Type alias | @legacy @beta
|
ITelemetryGenericEventExt
| Interface | @legacy @beta
|
ITelemetryErrorEventExt
| Interface | @legacy @beta
|
ITelemetryPerformanceEventExt
| Interface | @legacy @beta
|
ITelemetryLoggerExt.sendTelemetryEvent()
| Method | @legacy @beta
|
ITelemetryLoggerExt.sendErrorEvent()
| Method | @legacy @beta
|
ITelemetryLoggerExt.sendPerformanceEvent()
| Method | @legacy @beta
|
Change details
Commit: 42b77ab
Affected packages:
- @fluidframework/telemetry-utils
⬆️ Table of contents
Legacy API Changes
Remove IIdCompressorCore from legacy API surface (#27146)
The IIdCompressorCore interface has been removed from the @legacy API surface and is now @internal. This was previously deprecated in 2.92.0.
The return types of createIdCompressor and deserializeIdCompressor have been narrowed from IIdCompressor & IIdCompressorCore to IIdCompressor.
Migration
serialize(): Use theserializeIdCompressor(compressor, withSession)free function instead of callingcompressor.serialize(withSession)directly.takeNextCreationRange(),takeUnfinalizedCreationRange(),finalizeCreationRange(),beginGhostSession(): These are internal runtime operations that should not be called by external consumers. If you depend on these APIs, please file an issue on the FluidFramework repository describing your use case.- Return types of
createIdCompressor/deserializeIdCompressor: Type your variables asIIdCompressorrather thanIIdCompressor & IIdCompressorCore.
Change details
Commit: a0d3a13
Affected packages:
- @fluidframework/id-compressor
⬆️ Table of contents
🛠️ Start Building Today!
Please continue to engage with us on GitHub Discussion and Issue pages as you adopt Fluid Framework!