14-day Cloud trial
Start today. For free.

One editor. 50+ features. Zero constraints. After your trial, retain the advanced features.

Try Professional Plan for FREE
PricingContact Us
Log InGet Started Free

Building for collaboration using the Fluid framework

February 15th, 2024

4 min read

A fluid and winding ribbon appears alongside a window, curly braces, a rocket, symbolic of the Fluid framework's development speed

Written by

Joe Robinson


Developer Insights

Collaboration is a key feature that a growing number of people are actively looking for in web apps and software. However, the concepts involved can be complex, and take time to implement. A framework that unblocks some of this difficulty with reliable abstraction could help, so let’s dig into how the Fluid framework achieves it. 

The Fluid framework is a library that allows consistent, real-time collaboration across web applications. It makes use of JavaScript or Typescript, as well as having the ability to integrate into existing frameworks and libraries such as React, Angular, and Vue. 

This article explores how the Fluid framework builds a collaborative experience for customers simultaneously working together.


  • Frameworks are designed to increase speed and efficiency when building web apps. 
  • At Tiny, we want to better support our community, so this article looks into the Fluid framework to aid your decisions about whether to use it, or not.
  • The article looks closely at Fluid’s collaboration building abilities, and whether it’s worth installing.

What is the Fluid framework?

Fluid is an open source framework released in 2020, by Microsoft, that’s designed to make real-time collaboration easier and faster. It does this by abstracting a lot of the complexity involved with collaboration, and moving the change processing to the client rather than concentrating it in the server.

Fluid framework collaboration concepts

When a client makes a change, Fluid handles that change and passes it on by representing the change as an “operation” on the existing data. By sending only the operation and not the entire changed data, the state can be made consistent across clients without a large amount of wait time for different clients across the network (low-latency). 

This concept, which Fluid is designed around, is called the Operation Transform.

✏️NOTE: The complete story about the Operation Transform concept is beyond the scope here, but for more on the Operation Transform concept, there’s a useful guide available: when TinyMCE offered real-time collaboration (sunsetted in January, 2023), the development included thorough research and development, which you can read about in the TinyMCE articles on the R&D concept

How the Fluid framework builds collaboration

The Fluid framework’s design keeps clients synchronized with each other by starting off with a shared container. The container holds what’s called a shared object. That container, holding the shared object, is attached to the Fluid framework client. The client then passes on changes that it detects from one client to all clients by running an event listener to detect changes, specifically the afterChanged event.

Fluid framework collaboration example

The “hello world” demo for the Fluid Framework is the “Dice Roller” web app. You can see the source in the demo GitHub repository, and the most important points follow:

1. The Fluid Framework shared container

The following asynchronous functions show the creation of the Fluid demo containers, which hold the shared object:

const createNewDice = async () => {
  const { container } = await client.createContainer(containerSchema);
  const dice = container.initialObjects.diceTree.schematize(treeConfiguration)
  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.schematize(treeConfiguration)
  renderDiceRoller(dice, root);

The dice constant has the initialObject that clients see when they start collaborating. But there are more properties after the initialObject. These are defined earlier in the demo app.js file:

The schema:

const containerSchema = {
  initialObjects: { diceTree: SharedTree },

And the tree configuration:

const treeConfiguration = new TreeConfiguration(
  () =>
    new Dice({
      value: 1,

These are both essential to how the Fluid Framework builds collaboration at a deeper level and the schema is how Fluid models data. Collaboration’s main goal is to eventually achieve consistency across clients. Starting off with a clear schema supports this goal.

2. Attaching to the Fluid framework client

Setting up the client at the beginning of the demo, and then the call to createContainer() are specifically attaching the container to the client:


const client = new TinyliciousClient();

And here, as seen in the previous section on creating the container:

const createNewDice = async () => {
    const { container } = await client.createContainer(containerSchema);

3. Handling change, and passing it on for eventual consistency

The final section of JavaScript in the demo listens for change, and ensures it’s passed on to all clients:

    const updateDice = () => {
    const diceValue = dice.value;
    diceElem.textContent = String.fromCodePoint(0x267f + diceValue);
    diceElem.style.color = `hsl(${diceValue * 60}, 70%, 30%)`;
    Tree.on(dice, "afterChange", updateDice);
    window["fluidStarted"] = true;

Fluid framework testing and production

The demo Fluid web app “Dice Roller” uses a testing client called Tinylicious. In production, a reliable relay like the Azure Fluid Relay is recommended. 

The documentation says the Fluid framework can work with any compatible service implementation. And the ability to scale with demand appears to be the main criteria for a compatible relay service for synching up changed states across clients.

Fluid framework in the long term

You can expect there’ll be updates from time to time on the Microsoft developer blog when there’s changes in the Fluid project overall.

 If the project continues long term, or if development slows in favor of other priorities, the Fluid framework GitHub discussion board might be a good place to seek further updates. That, and any Stack Overflow activity could show hints of what’s to come in the future.

Why you should look closer at frameworks

The key principle behind the use of frameworks for web app development, is increased efficiency and speed. The Fluid framework is just one, new example of how something complex can get an abstraction to make it easier to implement useful functionality for your customers.

Similarly, the TinyMCE rich text editor saves you time creating a WYSIWYG editor from scratch, and when adding TinyMCE to your project, there’s an array of dedicated framework integrations:

Contact us if you have any questions, or are interested in how TinyMCE can enhance and upgrade your framework’s rich text editing.

byJoe Robinson

Technical and creative writer, editor, and a TinyMCE advocate. An enthusiast for teamwork, open source software projects, and baking. Can often be found puzzling over obscure history, cryptic words, and lucid writing.

Related Articles

  • Developer InsightsApr 18th, 2024

    Understanding byte offset and WYSIWYG cursor position

Join 100,000+ developers who get regular tips & updates from the Tiny team.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Tiny logo

Stay Connected

SOC2 compliance badge


© Copyright 2024 Tiny Technologies Inc.

TinyMCE® and Tiny® are registered trademarks of Tiny Technologies, Inc.