{"id":10906,"library":"fluid-framework","title":"Fluid Framework Core Client Libraries","description":"The `fluid-framework` package serves as the primary client-side entry point for building collaborative applications with Fluid Framework. It bundles core Fluid Framework client libraries, including the `IFluidContainer` interface and various Distributed Data Structures (DDSes) like `SharedTree` and the now legacy `SharedMap`. The current stable version is 2.93.0, with minor releases occurring frequently, often including new features and breaking changes. This package abstracts away many individual Fluid package dependencies, simplifying development. While it provides the core collaborative primitives, it requires a separate service client (e.g., `@fluidframework/azure-client` or `@fluidframework/tinylicious-client`) to connect to a Fluid service. Its key differentiators include real-time, low-latency collaboration primitives, robust data modeling with `SharedTree`, and a comprehensive API for managing collaborative sessions.","status":"active","version":"2.93.0","language":"javascript","source_language":"en","source_url":"https://github.com/microsoft/FluidFramework","tags":["javascript","typescript"],"install":[{"cmd":"npm install fluid-framework","lang":"bash","label":"npm"},{"cmd":"yarn add fluid-framework","lang":"bash","label":"yarn"},{"cmd":"pnpm add fluid-framework","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required to connect to Azure Fluid Relay service.","package":"@fluidframework/azure-client","optional":true},{"reason":"Required for local development and testing with Tinylicious service.","package":"@fluidframework/tinylicious-client","optional":true},{"reason":"Required to connect to OneDrive/SharePoint Fluid services (currently in Beta).","package":"@fluidframework/odsp-client","optional":true},{"reason":"Provides React hooks and components for integrating Fluid content into React applications.","package":"@fluidframework/react","optional":true},{"reason":"Routes Fluid telemetry to Azure Application Insights.","package":"@fluidframework/app-insights-logger","optional":true}],"imports":[{"note":"The `IFluidContainer` interface is a core public API. While `fluid-framework` primarily targets ESM, other associated packages like `@fluidframework/react` are ESM-only since v2.90.","wrong":"const IFluidContainer = require('fluid-framework');","symbol":"IFluidContainer","correct":"import { IFluidContainer } from 'fluid-framework';"},{"note":"`SharedTree` is the recommended modern Distributed Data Structure (DDS) and is part of the public API, imported directly from `fluid-framework`.","wrong":"import { SharedTree } from 'fluid-framework/beta';","symbol":"SharedTree","correct":"import { SharedTree } from 'fluid-framework';"},{"note":"Service clients like `TinyliciousClient` are provided by separate packages and are not re-exported directly from `fluid-framework`.","wrong":"import { TinyliciousClient } from 'fluid-framework';","symbol":"TinyliciousClient","correct":"import { TinyliciousClient } from '@fluidframework/tinylicious-client';"},{"note":"Alpha-level APIs, such as `TreeAlpha`, must be imported from their specific subpath (`fluid-framework/alpha`).","wrong":"import { TreeAlpha } from 'fluid-framework';","symbol":"TreeAlpha","correct":"import { TreeAlpha } from 'fluid-framework/alpha';"}],"quickstart":{"code":"import { SharedTree } from \"fluid-framework\";\nimport { TinyliciousClient } from \"@fluidframework/tinylicious-client\";\nimport { TreeConfiguration, SchemaFactory } from \"@fluidframework/tree\";\n\nconst client = new TinyliciousClient();\n\n// Define the schema for our collaborative tree\nconst sf = new SchemaFactory(\"my-app\");\n\nclass MyTreeNode extends sf.object(\"MyTreeNode\", {\n  message: sf.string,\n  timestamp: sf.number,\n  children: sf.array(sf.reference(\"MyTreeNode\"))\n}) {}\n\nconst appSchema = new TreeConfiguration(\n  [MyTreeNode],\n  () => new MyTreeNode({ message: \"Hello from Fluid!\", timestamp: Date.now(), children: [] })\n);\n\nconst containerSchema = {\n  initialObjects: {\n    myTree: SharedTree\n  }\n};\n\nasync function startFluidClient() {\n  const containerId = location.hash.substring(1);\n  let container;\n  if (!containerId) {\n    // Create a new container\n    ({ container } = await client.createContainer(containerSchema));\n    const tree = container.initialObjects.myTree.schematize(appSchema);\n    tree.root.message = \"Initial message\";\n    tree.root.timestamp = Date.now();\n    const newChild = new MyTreeNode({ message: \"First child\", timestamp: Date.now(), children: [] });\n    tree.root.children.insertAtStart(newChild);\n    const id = await container.attach();\n    location.hash = id;\n    console.log(\"New container created with ID:\", id);\n  } else {\n    // Get existing container\n    ({ container } = await client.getContainer(containerId, containerSchema));\n    console.log(\"Existing container loaded with ID:\", containerId);\n  }\n\n  const tree = container.initialObjects.myTree.schematize(appSchema);\n\n  // Event listener for changes\n  tree.events.on(\"treeChanged\", () => {\n    console.log(\"Tree changed: Current message is \", JSON.stringify(tree.root.message));\n    console.log(\"Number of children: \", tree.root.children.length);\n  });\n\n  // Update the tree after 5 seconds\n  setTimeout(() => {\n    const newMessage = `Message from client ${Math.random().toFixed(2)}`;\n    tree.root.message = newMessage;\n    const newChild = new MyTreeNode({ message: `Another child ${Math.random().toFixed(2)}`, timestamp: Date.now(), children: [] });\n    tree.root.children.insertAtEnd(newChild);\n    console.log(`Updated tree message to: ${newMessage}`);\n  }, 5000);\n}\n\nstartFluidClient().catch(console.error);","lang":"typescript","description":"This quickstart demonstrates how to create or load a Fluid container, initialize a SharedTree with a defined schema, and interact with its collaborative data, including event listeners for changes."},"warnings":[{"fix":"Ensure that `minVersionForCollab` is explicitly set within your container configuration object, typically when calling `createContainer()` or `getContainer()` via a service client. A common value is `1` for basic scenarios.","message":"The `minVersionForCollab` property is now a non-optional requirement in Fluid Framework client configurations, necessitating explicit specification when creating or loading containers.","severity":"breaking","affected_versions":">=2.93.0"},{"fix":"Migrate your React-based Fluid applications to use ECMAScript Modules (ESM) for imports. This generally involves setting `\"type\": \"module\"` in your `package.json` and ensuring your build system is configured to output ESM.","message":"The `@fluidframework/react` package, used for integrating Fluid content into React applications, no longer supports CommonJS (CJS) imports. It is now exclusively an ECMAScript Module (ESM).","severity":"breaking","affected_versions":">=2.90.0"},{"fix":"Update your event listener signatures for the `IDirectory.cleared` event to accommodate the newly added `path` parameter.","message":"The `cleared` event for `IDirectory` (and potentially other similar DDSes) now includes a `path` parameter in its signature, which may affect existing event listeners.","severity":"breaking","affected_versions":">=2.81.0"},{"fix":"Refactor your code to avoid using number keys directly in `LatestMap`. Convert number keys to strings before using them, or consider migrating to `SharedTree` if structured data with numeric identifiers is a core requirement.","message":"`LatestMap`, a specific type of Distributed Data Structure, has removed support for number keys.","severity":"breaking","affected_versions":">=2.80.0"},{"fix":"For all new development and for migrating existing `SharedMap` instances, it is strongly recommended to use `SharedTree` instead, as it offers enhanced capabilities, better type safety, and is the actively developed DDS for collaborative data modeling.","message":"`SharedMap` is now considered a legacy Distributed Data Structure (DDS) as of Fluid Framework version 2.0. While still functional, it is not recommended for new development.","severity":"deprecated","affected_versions":">=2.0.0"},{"fix":"Always ensure you are importing APIs from their correct subpath according to their stability level. Using unstable APIs carries risks and requires a more constrained version range (`~`) in your `package.json`.","message":"Fluid Framework APIs are segmented by their stability level (public, beta, alpha, legacy) and require importing from specific package subpaths (e.g., `fluid-framework`, `fluid-framework/beta`, `fluid-framework/alpha`).","severity":"gotcha","affected_versions":"*"},{"fix":"Configure your `package.json` dependencies with `\"fluid-framework\": \"^x.y.z\"` for public APIs and `\"fluid-framework/beta\": \"~x.y.z\"` for beta/alpha APIs to manage stability risks effectively.","message":"When declaring dependencies in `package.json`, use a `^` (caret) version range for public Fluid Framework APIs. However, for unstable (beta or alpha) APIs, a more constrained `~` (tilde) version range is recommended to minimize exposure to unannounced breaking changes.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add `{ minVersionForCollab: 1 }` or an appropriate version to your `containerSchema` when calling `client.createContainer()` or `client.getContainer()`.","cause":"`minVersionForCollab` is missing from the container configuration object.","error":"Error: minVersionForCollab must be a non-negative number. Received: undefined"},{"fix":"Configure your project for ECMAScript Modules (ESM) by setting `\"type\": \"module\"` in your `package.json` and using `import` statements.","cause":"Attempting to use `require()` for ESM-only Fluid Framework client packages (e.g., `@fluidframework/react`) in a CommonJS environment.","error":"TypeError: require is not a function in ES module scope"},{"fix":"Import beta APIs from `fluid-framework/beta` and alpha APIs from `fluid-framework/alpha`. For example: `import { TreeAlpha } from 'fluid-framework/alpha';`.","cause":"Attempting to import a beta or alpha API directly from the root `fluid-framework` package instead of its specific subpath.","error":"Property 'TreeAlpha' does not exist on type 'typeof import(\"fluid-framework\")'."},{"fix":"Convert number keys to strings before using them in `LatestMap`, or refactor to use `SharedTree` for structured data where numeric identifiers can be modeled differently.","cause":"Attempting to use a number as a key in a `LatestMap` instance after Fluid Framework v2.80.","error":"Type 'number' is not assignable to type 'string'."}],"ecosystem":"npm"}