Real-time. Multiuser. Collaboration.

Empower collaborative innovation with Fluid Framework's seamless, high-performance tech stack for real-time applications.

Get started with Fluid Framework today!

Who's using Fluid Framework





Microsoft Loop

Microsoft Teams


Power Apps



easy to use image

Easy to use

Transform your collaborative experience with our developer friendly framework - where simplicity meets powerful functionality effortlessly. The framework provides usability that drives innovation within Microsoft and across the industry by dramatically lowering the difficulty and cost of building innovative, collaborative software.

github logo

Open source

We believe that an open, inclusive, and respectful community will help shape a better future for this project. That's why Fluid Framework is made available for FREE as an Open Source project under the MIT license.

speed and performance image

Industry-leading speed & performance

Unleash unparalleled speed and performance with our cutting-edge solution for building real-time collaborative applications. Collaborative features are only successful if they are fast, scale to large data and user bases. Fluid offers an approachable programming model that leverages mainstream web technology while delivering best-in-class performance.

See How It Works

Sample Code

Sample Output

import { SharedTree, TreeViewConfiguration, SchemaFactory, Tree } from "fluid-framework";
import { TinyliciousClient } from "@fluidframework/tinylicious-client";

const client = new TinyliciousClient();
const containerSchema = {
    initialObjects: { diceTree: SharedTree },

const root = document.getElementById("content");

// The string passed to the SchemaFactory should be unique
const sf = new SchemaFactory("fluidHelloWorldSample");

// Here we define an object we'll use in the schema, a Dice.
class Dice extends sf.object("Dice", {
    value: sf.number,
}) {}

// Here we define the tree schema, which has a single Dice object.
// We'll call viewWith() on the SharedTree using this schema, which will give us a tree view to work with.
const treeConfiguration = new TreeViewConfiguration({ schema: Dice });

const createNewDice = async () => {
    const { container } = await client.createContainer(containerSchema);
    const view = container.initialObjects.diceTree.viewWith(treeConfiguration);
    // Because we're creating a new document, the tree must be initialized with some data.
    // Doing this step before attaching is also a good idea as it ensures other clients will never see the
    // tree in an uninitialized state.
    view.initialize(new Dice({ value: 1 }));
    // Get the root node of the view, which contains the tree's data
    const dice = view.root;
    // Attaching the container gives it a backing file and makes it visible to other clients.
    const id = await container.attach();
    renderDiceRoller(dice, root);
    return id;

const loadExistingDice = async (id) => {
    const { container } = await client.getContainer(id, containerSchema);
    const dice = container.initialObjects.diceTree.viewWith(treeConfiguration).root;
    renderDiceRoller(dice, root);

async function start() {
    if (location.hash) {
        await loadExistingDice(location.hash.substring(1));
    } else {
        const id = await createNewDice();
        location.hash = id;

start().catch((error) => console.error(error));

// Define the view
const template = document.createElement("template");

template.innerHTML = `
    .wrapper { text-align: center }
    .dice { font-size: 200px }
    .roll { font-size: 50px;}
<div class="wrapper">
    <div class="dice"></div>
    <button class="roll"> Roll </button>

const renderDiceRoller = (dice, elem) => {

    const rollButton = elem.querySelector(".roll");
    const diceElem = elem.querySelector(".dice");

    // Set the value on the persisted Dice object to a random number between 1 and 6.
    rollButton.onclick = () => {
        dice.value = Math.floor(Math.random() * 6) + 1;

    // Get the current value of the shared data to update the view whenever it changes.
    const updateDice = () => {
        const diceValue = dice.value;
        // Unicode 0x2680-0x2685 are the sides of a dice (⚀⚁⚂⚃⚄⚅)
        diceElem.textContent = String.fromCodePoint(0x267f + diceValue); = `hsl(${diceValue * 60}, 70%, 30%)`;

    // Use the afterChange event to trigger a rerender whenever the value changes.
    Tree.on(dice, "afterChange", updateDice);
    // Setting "fluidStarted" is just for our test automation
    window["fluidStarted"] = true;

Fluid Framework in the Cloud


Azure Fluid Relay

Azure Fluid Relay is a cloud service that enables real-time collaboration on shared data models. It is a fully managed service that provides a secure, scalable, and reliable way to connect clients to each other and to the data models they share.

SharePoint Embedded

Microsoft SharePoint Embedded is a cloud-based file and document management system suitable for use in any application. It is a new API-only solution which enables app developers to harness the power of the Microsoft 365 file and document storage platform for any app, and is suitable for enterprises building line of business applications and ISVs building multi-tenant applications.