Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
158740 stories
·
33 followers

Progressive Enhancement inside of JavaScript [blog]

1 Share

Lately I've had the opportunity to travel by train and coach, during which time I also tend to work. It's really only during these periods that I'm reminded of how web sites fail so terribly over a slow connection.

On the odd occasion I can be guilty of this too. I had a tiny tool that takes markdown and renders it for quick reading (no apps, or split view in VS Code, etc). When I loaded it up on the train, the page asked me to drop the file in to be rendered, which I dutifully did, only for the page to load the source markdown.

It's nothing new, but Progressive Enhancement doesn't only apply to HTML being enhanced with JavaScript. It also applies within JavaScript. Sometimes this was the cut the mustard test, but sometimes it's about thinking laterally about JavaScript. In particular, can I capture the user's intent if they try to interact with my page before it's fully ready?

Below I've made a visual demonstration of the issue, and the effect after I fixed the logic. It shows the browser throttled to "good 2G" network connectivity, and first I try to drop the markdown file and the browser (naturally) assumes I want to open the file. The result being the browser navigates away from the page to render the raw markdown - not what I wanted.

The second part of the video shows with the same throttled connection, I can drop the file, and the page remains in place with a "Loading" indicator. The browser status shows that more files are being loaded (over the network from esm.sh) and when those settle down after 10 seconds, the fully rendered page loads. It's slow, but it got there in the end.

The original source code had the JavaScript at the end of the HTML but one of the first tasks was to import the markdown parsing module from esm.sh. This is a significant amount of code. Then it imports highlightjs (which might not even be required). Although this was very much a quickly thrown together project, it does pull 600kB (compressed) - which feels rather heavy and I'd like to optimise if this wasn't just for me.

That 600kB, decompressed to 1.3MB, has to be downloaded and parsed before the browser parses the "author code", i.e. my code, that does the rendering of the markdown file.


By prioritising the user interaction and including only the required JavaScript both inline and directly after the source HTML that's going to encourage the user to interact, I'm able to catch the interaction and queue up the work until the prerequisite functionality is loaded.

That means breaking out the event handler binding, queue logic and simple visual feedback from the main body of JavaScript.

The result is that, even over a GPRS connection, the full interactivity still works, even if it takes nearly 2 minutes to complete.


This particular project is designed not to have a backend at all (that's just a constraint I set myself). Though I can see how this could actually upload the markdown to a server for rendering. I imagine I can use Netlify ODB - though I haven't measured the timings, I'd bet that it's still faster than 2 minutes over GPRS.


This is not a new method by any measure at all. I was only reminded of it because I was on a train. Admittedly my daily client work is deep in backend API work, so I don't often get to take a closer look at front end JavaScript so much these days!

Originally published on Remy Sharp's b:log

Read the whole story
alvinashcraft
33 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Trump’s AI testing plan is limited and vague

1 Share
A digital brain on a leash.

The Trump administration's framework for assessing potential cybersecurity risks posed by advanced AI reportedly has no interest in testing open models. Axios reports that not only do the voluntary guidelines outright exclude open models - meaning anyone can download them and inspect their core components - but the framework explicitly says it can't be used to restrict open models after they've been released.

The AI testing framework was created after President Trump signed an executive order in June, requesting that AI companies share their frontier models with the federal government prior to release to address cybersecurity concerns. AI c …

Read the full story at The Verge.

Read the whole story
alvinashcraft
33 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Introduction to Post-training

1 Share

This is the first article in a series about post-training. Follow along on Radar.

Before post-training, there was a major problem with LLMs: Almost nobody could use them. The story of post-training is also the story of how AI went from a research curiosity to a product used by about a billion people.

Post-training is the reason why a model behaves a certain way. This set of training techniques makes LLMs useful (e.g., able to chat with people and interact with AI agents), safe (e.g., aligned with human intentions), and more capable (e.g., through “reasoning” to tackle difficult tasks). Behavior is powerful, and doesn’t just mean holding a conversation or following a user’s instructions. Behavior includes making it possible for the model to use tools, like a calculator tool, a search API, or any application through an MCP. Behavior can even elevate a model’s intelligence, for example by teaching the model to use “reasoning”: that is, working through problems before giving a final answer rather than “guessing” or “memorizing.”

From GPT-3 to ChatGPT: The post-training revolution

GPT-3 showed up in June 2020. A completion engine, it followed patterns it had seen from its pretraining data, which were not predominantly chat conversations. Imagine scraping data on the internet: that pretraining data had a lot of questions that were followed by other questions—for example, on an exam template. GPT-3 was 175B parameters, large for its time, and it had a wide, general range of abilities, although many of them were latent.

If you gave GPT-3 a prompt like “Why do people like golden retrievers?” it might say something nonsensical:

Why do people like labrador retrievers?
Why do people like poodles?
10 Reasons You Should Adopt a Dog Today

These answers look absurd in isolation, but if you imagine a web page with a list of FAQ links, this is a perfectly reasonable next chunk of text. GPT-3 might have just been completing a listicle on a website, because it had seen millions of websites in its pretraining data.

The common way to nudge GPT-3 to answer a question back then was by prompt engineering with a Q&A template and few-shot examples.

Q: Why do people like labrador retrievers? A: Because they are friendly, loyal, and easy to train.
Q: Why do people like beagles? A: Because they are curious, great with kids, and have a gentle temperament.
Q: Why do people like golden retrievers? A:

Then, GPT-3 might say:

Because they are affectionate, patient, and make excellent family pets.

While this technique worked, it was brittle. If you forgot the few-shot examples, rephrased the question, or even added a space after “A:,” you’d get something completely different (possibly unhinged) that was far from a reasonable response.

In fact, if you were a researcher working with GPT-3 at the time, you probably at some point found the space at the beginning of the response ” Because they are gentle dogs.” annoying and would try to end your prompt with a space “A: ” instead of “A:”. In those cases, it was common for GPT-3 to go off a cliff and produce a drastically different response, sometimes completely off like “dogs dogs dogs dogs…” repeating indefinitely.

The reason behind the differing responses to “A:” and “A: ” is because “A:” might tokenize to one token while “A: ” tokenizes to two different tokens. The model literally sees different input sequences, each with different statistical completions in its training data. It’s like asking two completely different questions. While a space is a tiny syntactic change that is meaningless to a person, it becomes extremely meaningful to the model that now sees two different prompts (the tokens change!) with two very different statistical futures to complete.

You still encounter the modern equivalent of this when working with chat templates. If you forget to apply the model’s chat template and instead just concatenate 'User: ' + prompt + '\nAssistant: ', you’re sending the model a token sequence that it was not robustly trained on. The tokens are wrong, not the model. Post-training teaches the model to respond to specific token patterns (like <|im_start|>user\n in Qwen models). Not using them is like speaking to someone in a language they half-understand. However, most open source models will be trained to be at least somewhat robust without their templates too.

Under those circumstances, most people would assume AI still didn’t work. The model wasn’t trained to answer questions; its data wasn’t primarily conversation transcripts. Instead, it was trained to predict the next token in downloaded websites, articles, and documents.

Thankfully, this can all be fixed with post-training. And that’s when most people started to believe that AI had undergone a paradigm shift and just might work.

Post-training versus pretraining

Pretraining heavily influences the model’s knowledge capacity prior to post-training. The model gets raw intelligence during pretraining. Then, during post-training, that intelligence is made useful through behaviors like dialogue and reasoning. In a frontier lab, these two phases are such different processes that very different teams work on them.

A model’s factual knowledge about the French Revolution, its understanding of Python syntax, and its grasp of calculus all come from pretraining. Post-training primarily shapes which knowledge the model reaches for, how it presents that knowledge, what tone it uses, whether it declines certain requests, and whether it thinks step-by-step before answering, though targeted SFT on new domains can introduce information the model didn’t encounter in pretraining.

If a model gives a wrong answer about history, the root cause is likely in pretraining data, but the practical fix might still come through post-training—for example, teaching the model to use search tools, express uncertainty, or chain-of-thought verify its own claims. But if a model gives correct information in a condescending way or refuses to help with a reasonable request or fails to use tools when it should, those are squarely post-training problems.

Pretraining

The work of pretraining is centered around cleaning and curating large-scale data, optimizing the model toward relatively clear loss signals, and working with scaling laws given bounded compute.

In pretraining, the model learns to predict the next token across a large curated dataset, typically for one or a small number of passes over the training data, though some models train for multiple epochs, especially as high-quality data becomes scarce relative to compute budgets. This is where you’ll hear how a model is fed the entire internet’s worth of data to gain intelligence, although in practice nearly all of the data (often 90% or more) may be thrown out because it’s unsuitable for training.

Pretraining is an unsupervised process that runs at increasingly larger scales to match the size of the model. While scaling, thousands of experiments are used to understand what data mix, what architecture considerations, what compute optimizations, what hyperparameters can lead to the best results. There’s variance in each run due to stochasticity found in both software and hardware, so multiple experiments are needed to verify results. Because compute is limited and needs to be used sparingly, researchers will scale iteratively, expanding to the next, say, 10x compute budget, when they gain confidence in the right configuration. A full run isn’t possible to iterate on due to the compute cost and time it would take: The final run, often called the “god run,” can take over a month on thousands of GPUs.

Pretraining progress is typically very clearly measurable, using a metric like perplexity, which measures, roughly, the model’s average uncertainty per token. Lower is better, where 1 means the model knows with absolute certainty what token comes next. Meanwhile, a perplexity of 50 means the model’s predictions are, on average, as uncertain as if it were choosing uniformly among 50 equally likely tokens—though in practice, the distribution is peaked, not uniform.

Post-training

Rather than consuming hundreds of millions of tokens of internet data, post-training operates on far more intentional datasets for downstream tasks. These datasets include human-written demonstrations of ideal responses, human judgments about which responses from the model are better, and carefully designed functions that score the model’s outputs programmatically. They shape what “good” looks like.

Like pretraining, post-training can also be more effective with scaling data and compute. Specifically, massive compute budgets have been dedicated to post-training to learn reasoning capabilities (or the ability for models to “think step-by-step” to arrive at more logically sound answers), matching the scale of pretraining compute.

Post-training is messier than petraining, which has an elegant, clear optimization objective to minimize the loss over the next token prediction across a huge corpus. The goals of post-training are things like “be more helpful” or “don’t say harmful things.” Many of these objectives are inherently subjective and require human judgment, proxy models that approximate human judgment, or programmatic verifiers that can become elaborate or inefficient. The loss curves are noisier. The quality of the data and feedback matter even more.

The scale of post-training is also more complicated than in pretraining. Standard post-training remains relatively modest in compute: tens to hundreds of GPUs for days rather than thousands of GPUs for months needed in pretraining. This makes post-training for alignment highly amenable to rapid iteration; researchers can try something, observe results, form a hypothesis, and run again on a timescale of days.

The picture changes dramatically when post-training is used to develop reasoning capabilities. For reasoning models, the compute dedicated to post-training can easily account for half of the overall compute of the model. The gap between a standard instruct model and a reasoning model is increasingly a gap in post-training compute, not pretraining scale. This means post-training now spans a wide spectrum from fast, cheap, highly iterable fine-tuning runs to massive RL campaigns that rival pretraining in both cost and engineering complexity.

Why post-training matters

So why can’t we just stick with pretraining? It comes down to three main pieces: usability, safety, and capability.

Usability

A pretrained model is like if someone gave you a large download of Wikipedia in a single PDF. It’s a ton of knowledge that you can sift through, but there’s no way to easily understand what is going on in the data. Post-training gives the model the ability to integrate this information for you and respond to your request naturally. This extends to having longer multiturn conversations and following instructions. Without it, every user would need to be a prompt engineer. With it, anyone who can type a sentence can use the model.

Safety

A lot of data in pretraining can be toxic, biased, misleading, or outright dangerous. Or it might not be dangerous on its own, but when a model can integrate knowledge from different fields, it can create something novel that is dangerous.

The model has no inherent sense of what content is good or bad. It will follow any request, based on its pretraining data. To prevent that, you can add safety guardrails to the model in post-training, to refuse harmful requests like asking the model to build a bioweapon and avoid accidentally generating toxic content such as inappropriate sexual content (even if it wasn’t in the user’s request). This is also the place to teach the model to express uncertainty, when it doesn’t know something, whether that’s “I don’t know” or “that’s beyond my knowledge cutoff” or “as a large language model, I’m limited in my knowledge so please consult a healthcare professional.”

Making a model safe is part of a broader area in the AI research community called “alignment,”1 where the goal is to align the model with human values and preferences. Post-training is typically the main way to achieve that.

Model companies will usually have additional safeguards beyond post-training, including lightweight models that check whether the user’s request was safe, as a second layer of protection against responding to harmful requests.

Capability

Post-training doesn’t just make a model nicer or safer; it can make the model smarter at hard tasks. The clearest example is reasoning. A pretrained model might have all the mathematical knowledge needed to solve a complex word problem, but it might jump to an incorrect answer because it’s pattern-matching from pretraining data or pattern-matching from how to answer questions (e.g., with succinct immediate answers).

It turns out that making the model output more tokens before giving an answer (or “think longer”), results in better answers. This process is known as reasoning, and post-training can teach the model to reason more effectively. A more capable pretrained model is a more dangerous model if it’s not properly aligned. A more intelligent model is a less useful model to humans if it can’t communicate clearly. And, every point of improvement in a reasoning benchmark now maps to real revenue for companies deploying these models.

Superhuman performance

Can post-training push models beyond human-level performance? Yes, in specific domains.

In competitive programming, top reasoning models can now solve problems at a level that exceeds the vast majority of human competitive programmers. In math, models have achieved scores on Math Olympiad-level competitions that would place them among the top competitors in the world. In certain scientific domains, models have generated novel hypotheses and solutions that human experts found valuable.

This might seem paradoxical. If the model’s knowledge comes from human-generated data (in pretraining), and its behavior is shaped by human feedback (in post-training), how can it exceed human performance?

Two things make this possible. First, integration across domains. Research is about combining or mixing fields. Imagine mixing every possible field. The pretraining data aggregates knowledge from millions of sources, and no single human has read all of it. Second, post-training, particularly RL with reasoning, teaches the model to explore many approaches to a problem, far more than a human would try in a single sitting. A human might try one or two approaches to a hard math problem.

This means post-training is not just about making models mimic human behavior. It’s about pushing beyond it. This is especially possible to scale with verifier-based RL. In those scenarios, you can expect models to achieve superhuman performance in an expanding set of domains. Starting with verifiers that are very well-defined, easy to access, efficient, and cheap relative to the ROI of the model learning it. The limitation is no longer the model’s intelligence, but our ability to specify what “good” means through reward signals.


Footnote

  1. See Richard Ngo, Lawrence Chan, and Sören Mindermann’s “The Alignment Problem from a Deep Learning Perspective” and Iason Gabriel’s “Artificial Intelligence, Values, and Alignment.” ↩


Read the whole story
alvinashcraft
34 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

AI vs. Real People—Helping Teams Avoid Information Overload | Havva Sevay

1 Share

Havva Sevay: AI vs. Real People—Helping Teams Avoid Information Overload

Read the full Show Notes and search through the world's largest audio library on Agile and Scrum directly on the Scrum Master Toolbox Podcast website: http://bit.ly/SMTP_ShowNotes.

 

"It's still a tool. It can make mistakes, it can hallucinate. People don't really question it—and that's the danger." - Havva Sevay

 

This week's coaching conversation tackles a challenge Havva—and many Scrum Masters—are living right now: AI vs. real people. For some, AI is a useful tool; for others, it's a magic oracle that solves everything and makes people replaceable. Havva sees the real risk in teams that accept AI's confident answers without double-checking, and in leaders who use AI to generate massive documents and dump them on teams as finished decisions. Vasco pushes the conversation into the practical: when a flood of AI-generated information, requirements, and tool changes lands on a busy team, how do you help them cope? Havva's answer is to step back and ask the human questions first—what is the epic? what does the stakeholder actually want? what do we really need right now? Then she pulls out a deliberately low-tech move: forget AI for one second. Her team uses the Eisenhower matrix manually to separate what's important now from what can wait. AI is a great tool—but the filtering of what matters is still human work.

 

Self-reflection Question: When AI floods your team with information and options, what is your practice for helping them separate what matters now from the noise?

 

[The Scrum Master Toolbox Podcast Recommends]

🔥In the ruthless world of fintech, success isn't just about innovation—it's about coaching!🔥

Angela thought she was just there to coach a team. But now, she's caught in the middle of a corporate espionage drama that could make or break the future of digital banking. Can she help the team regain their mojo and outwit their rivals, or will the competition crush their ambitions? As alliances shift and the pressure builds, one thing becomes clear: this isn't just about the product—it's about the people.

 

🚨 Will Angela's coaching be enough? Find out in Shift: From Product to People—the gripping story of high-stakes innovation and corporate intrigue.

 

Buy Now on Amazon

 

[The Scrum Master Toolbox Podcast Recommends]

 

About Havva Sevay

 

Havva is a people-focused organizational development expert with a Master's in Business Administration and certification as a Scrum Master. She empowers teams and leaders through agile methodologies, modern leadership, and a strong feedback culture, fostering psychological safety and collaboration. Passionate about HR initiatives, Havva shapes people strategies, enhances employee experience, and drives inclusive, high-performing workplaces built on trust and engagement.

 

You can link with Havva Sevay on LinkedIn.





Download audio: https://traffic.libsyn.com/secure/scrummastertoolbox/20260805_Havva_Sevay_W.mp3?dest-id=246429
Read the whole story
alvinashcraft
34 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Vanishing Culture #6: What We've Learned with Vida Vojić & Alice Bridgwood

1 Share

What does it mean to preserve culture in an age of disappearing websites, platform-controlled media, and fragile digital memories? In the final episode of our special six-part series on Vanishing Culture, Future Knowledge hosts Dave Hansen and Chris Freeland sit down with musician and series host Vida Vojić and producer Alice Bridgwood to reflect on the conversations, ideas, and lessons that emerged throughout the series.

Read Vanishing Culture for free at the Internet Archive or purchase in print: https://archive.org/details/vanishing-culture-2026





Download audio: https://media.transistor.fm/d96c23cc/8ac24b22.mp3
Read the whole story
alvinashcraft
34 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Real-Time Collaborative Editing in a React Block Editor Using Yjs

1 Share

Real-Time Collaborative Editing in a React Block Editor Using Yjs

TL;DR: Learn how to add real-time collaboration to a React Block Editor using Yjs and WebSockets. This guide walks through building a shared editing experience with live document synchronization, user presence, and remote cursors without implementing custom conflict-resolution logic. You’ll also explore provider selection, production considerations, and best practices for creating reliable multi-user editing experiences.

Most developers think collaborative editing is simple, until they try building it.

Allowing multiple users to edit the same document in real-time involves much more than syncing text. You need to:

  • Handle concurrent changes,
  • Keep document state consistent,
  • Show active users,
  • Display remote cursors, and
  • Recover from connection interruptions without losing data.

That’s why features that feel effortless in tools like Google Docs are surprisingly difficult to implement.

If you’re building documentation portals, product specifications, incident reports, contracts, or knowledge bases, real-time collaboration is often a user expectation today.

The good news is that you don’t have to solve these challenges from scratch. The Syncfusion® React Block Editor provides a collaboration module designed to integrate with Yjs, a CRDT-based framework that manages synchronization and conflict resolution automatically, letting you focus on the editing experience rather than the underlying complexity.

In this guide, we’ll build a real-time collaborative editor using React, TypeScript, Yjs, and WebSockets. We’ll cover document synchronization, user presence, remote cursors, choosing the right Yjs provider, and key considerations for production deployments.

When does real-time collaboration make sense?

Real-time collaboration is ideal when multiple users need to edit the same document simultaneously while seeing live updates, presence indicators, and remote cursors.

Common use cases include:

  • Product specifications and PRDs,
  • Legal drafts and contract reviews,
  • Incident reports and postmortems,
  • Launch plans and project documentation,
  • OKR and team planning documents.

However, this approach may not be the best fit for:

  • Large wiki-style document networks,
  • Fully offline mobile applications, and
  • Scenarios that require direct device-to-device CRDT synchronization without a server.

Understanding what “real-time collaboration” actually means

Before diving into the implementation, it’s useful to understand a few concepts that power the collaborative experience.

CRDTs: The foundation of conflict-free editing

At the heart of Yjs is a Conflict-Free Replicated Data Type (CRDT). A CRDT allows multiple users to edit shared content simultaneously while ensuring every participant eventually sees the same document state.

The practical benefit is simple: two users can make changes at the same time without accidentally overwriting one another’s work.

Awareness: Knowing who’s doing what

Collaboration isn’t just about synchronizing content. Users also need context about other participants.

Yjs uses an awareness layer to share temporary information such as:

  • Cursor positions,
  • Text selections,
  • User names, and
  • Avatar information.

Because awareness data is temporary, it disappears when a user disconnects and doesn’t become part of the document itself.

Shared document state

Actual document content lives inside a shared Y.Doc file. Unlike awareness data, modifications stored in the document persist and can be synchronized across reconnects and future editing sessions.

Together, the shared document and awareness layer create the experience users expect from modern collaborative applications.

Why real-time collaboration matters

Modern editors need to support more than rich text. Users expect teams to create, review, and update content together without worrying about version conflicts or overwritten changes.

The Syncfusion React Block Editor treats content as independent blocks, such as paragraphs, headings, tables, callouts, and code snippets, making it easier to edit and organize content while maintaining a smooth writing experience. When combined with Yjs, both content changes and document structure stay synchronized across connected users.

This enables two key capabilities:

  • Edit simultaneously without conflicts: Yjs automatically resolves concurrent changes, so that multiple users can work in the same document at the same time.
  • See collaboration in real-time: Remote cursors, selections, and user presence indicators make it easy to understand who is editing and where changes are happening.

What you get out of the box

The collaboration module builds on Yjs and works alongside existing Block Editor features such as slash commands, rich text formatting, drag-and-drop, mentions, labels, paste cleanup, and accessibility support.

Key capabilities include:

  • Real-time multi-user editing with automatic conflict resolution.
  • Live user presence, selections, and remote cursors.
  • Per-user undo and redo, allowing users to revert only their own changes.
  • Synchronized rich text formatting, including headings, lists, links, colors, alignment, and inline styles.
  • Mention and label synchronization with metadata preserved across all users.
  • Support for multiple Yjs providers, including y-websocket, y-webrtc, Hocuspocus, Liveblocks, PartyKit, and more.

Whether someone is updating text, reordering sections, or adding a new callout block, every connected user sees changes reflected in real-time.

How real-time collaboration works

Behind the scenes, collaboration relies on three components: a shared Yjs document, a provider that synchronizes connected clients, and the Block Editor that renders and updates content.

Yjs collaboration

The process is straightforward:

  1. Each client initializes a Y.Doc file and creates a shared Y.XmlFragment called blockeditor.
  2. A YjsAdapter provides the editor with access to the Yjs runtime and the shared fragment.
  3. A Yjs provider connects all clients to the same collaboration room.
  4. The React Block Editor renders content from the shared fragment and writes local changes back to it. Yjs then automatically synchronizes those changes across all connected clients.
  5. When awareness is enabled, cursor positions, selections, and user information are exchanged through a separate channel.

As a result, multiple users can edit the same document simultaneously while keeping content, structure, and collaboration state synchronized.

Choosing the right Yjs provider

The Yjs provider you choose determines how clients connect, synchronize data, and handle persistence. The best option depends on your deployment requirements, scalability needs, and whether you want to manage the infrastructure yourself.

Provider Transport Persistence Signaling/Auth Best for
y-webrtc Peer-to-peer None by default Public signaling by default; no auth Local development, demos, single-session prototypes
y-websocket WebSocket None by default You provide the server and auth Self-hosted staging and small production
Hocuspocus WebSocket Pluggable (Redis, Postgres) Token-based auth, extensions Scalable self-hosting with persistence and auth
Liveblocks Managed WebSocket Hosted Hosted auth, REST API Teams that want a fully managed backend with devtools
PartyKit Serverless on Cloudflare Optional Durable Object persistence Cloudflare auth Serverless deployments, prototypes with persistence
y-indexeddb None (local) Browser only None Offline persistence in a single browser

For production environments:

  • y-websocket offers maximum control,
  • Hocuspocus adds persistence and authentication capabilities, and
  • Liveblocks provides a managed collaboration infrastructure with minimal operational overhead.

Build it yourself or start with existing collaboration support?

When planning collaborative editing, it’s easy to underestimate how much work exists beyond the editor UI. Synchronization, conflict handling, user presence, offline recovery, and persistence often require significantly more effort than the editing experience itself.

The table below compares some of the key responsibilities involved in building a collaborative editor from scratch versus using the Syncfusion React Block Editor with Yjs.

Feature Build yourself Syncfusion + Yjs
CRDT Design and implement CRDT, merge strategies, and conflict resolution from scratch. Uses Yjs’s production-tested CRDT with automatic conflict-free synchronization.
Real-time synchronization Build custom synchronization, diffing, patch generation, and nested content updates. Automatic incremental synchronization for content, properties, and document structure.
Presence & collaboration Implement cursors, selections, user awareness, and presence using custom protocols. Built-in real-time cursors, selections, user presence, and awareness through Yjs.
Provider & offline sync Build custom WebSocket messaging, offline persistence, and multi-device synchronization. Built-in WebSocket providers, offline persistence, and seamless multi-device synchronization.
Production readiness Requires validation for scalability, offline support, conflict recovery, and performance. Enterprise-ready with proven scalability, offline synchronization, and automatic recovery.

Building a collaborative editor involves much more than rendering content. By combining the Syncfusion React Block Editor with Yjs, you can focus on creating user-facing features while relying on a proven foundation for synchronization, presence, and shared editing experiences.

Building a real-time collaborative React Block Editor using Yjs

Let’s build a collaborative editor using Vite, React, TypeScript, Yjs, and the Block Editor.

Step 1: Create the project

Start by scaffolding a new React TypeScript application and installing the required packages:

npm create vite@latest collab-editor -- --template react-ts    
cd collab-editor    
npm install @syncfusion/ej2-react-blockeditor yjs y-websocket

Step 2: Configure the editor theme

Next, replace the contents of the src/index.css file with the following imports:

@import "@syncfusion/ej2-base/styles/tailwind3.css"; 
@import "@syncfusion/ej2-inputs/styles/tailwind3.css"; 
@import "@syncfusion/ej2-popups/styles/tailwind3.css";
@import "@syncfusion/ej2-buttons/styles/tailwind3.css"; 
@import "@syncfusion/ej2-splitbuttons/styles/tailwind3.css";
@import "@syncfusion/ej2-navigations/styles/tailwind3.css";
@import "@syncfusion/ej2-dropdowns/styles/tailwind3.css";
@import "@syncfusion/ej2-react-blockeditor/styles/tailwind3.css";

If your application already uses a different design system, replace tailwind3 with themes such as fluent, material, bootstrap5, material-dark, or bootstrap5-dark to match the rest of your UI.

Step 3: Create a collaboration hook

To keep the editor integration clean, create a dedicated collaboration hook. This hook manages the Y.Doc, shared Y.XmlFragment, Yjs provider, and the collaboration adapter throughout the component’s lifecycle, and automatically cleans up resources when the component is unmounted.

Refer to the code in the src/hooks/useCollaboration.ts. file

Step 4: Connect the editor

With the collaboration hook in place, the final step is to connect it to the Block Editor.

The following src/App.tsx file brings everything together by integrating the collaboration hook, rendering the editor, and displaying collaboration details such as connection status and active users. Once configured, multiple clients connected to the same room can edit the document in real-time.

Refer to the code in the src/App.tsx file and run the application.

Step 5: Run a local WebSocket server

To synchronize changes across multiple browser sessions, you’ll need a y-websocket server running locally.

First, install the WebSocket server:

npm install -g @y/websocket-server

Then, start the server in a separate terminal:

npx y-websocket

By default, the server runs on ws://localhost:1234. The connection URL configured in the App.tsx file already points to this address, so the editor can connect and begin synchronizing changes immediately.

Step 6: Test the real-time collaboration experience

With both npm run dev and npx y-websocket running, it’s time to verify that collaboration is working as expected.

  1. Open the application in two browser windows at http://localhost:5173.
  2. Make sure both windows display the same initial content and show the Connected status.
  3. In the first window, edit any paragraph. The changes should appear in the second window almost instantly.
  4. In the second window, place the cursor in a different location. The first window should display the user’s presence, including their remote cursor and participant information.
  5. Refresh both windows and reconnect. If your chosen provider supports persistence, the shared document state will be restored automatically.
Real-time collaborative editing in React Block Editor using Yjs
Real-time collaborative editing in React Block Editor using Yjs

At this point, you have a working collaborative editor with real-time synchronization, user presence, and shared editing capabilities.

Real-world scenario: Managing a product launch document

Consider a product team preparing for a major release. The product manager maintains the launch plan, the engineering lead documents technical risks, the design team updates messaging and assets, and the legal team reviews compliance requirements. Instead of passing documents back and forth, everyone contributes to the same document simultaneously.

Using the React Block Editor with Yjs, the team built a React application where each section, such as headings, paragraphs, tables, callouts, and lists, is represented as an editable block within a shared document. The editor connects to a y-websocket server, allowing changes to synchronize instantly across all participants.

With collaboration awareness enabled, team members can see active users, remote cursors, and selection highlights in real-time. This makes it easy to identify who is working on which section and reduces duplicate effort during reviews and updates.

The outcome

  • Faster document creation: Multiple contributors can draft content simultaneously instead of waiting for handoffs.
  • Fewer editing conflicts: Changes are synchronized automatically, and collaboration-aware undo/redo ensures users only revert their own edits.
  • Reusable collaboration pattern: The same approach can be applied to other team scenarios, including incident reports, quarterly planning documents, and contract reviews.

For teams that regularly collaborate on shared content, real-time editing helps reduce coordination overhead and keeps everyone working from a single source of truth.

Best practices for real-time collaborative editing

A few implementation choices can make a significant difference as your collaborative editor grows from a prototype to a production application:

  • Choose the right provider for your environment: Use y-webrtc or PartyKit for development and experimentation, y-websocket or Hocuspocus for self-hosted deployments, and Liveblocks if you prefer a managed service.
  • Use consistent room identifiers: Each room ID should uniquely map to a single document to ensure users join the correct collaboration session.
  • Integrate with your identity system: Usernames, avatars, and colors should come from the same identity source used throughout your application for a consistent experience.
  • Consider offline support: Pairing Yjs with y-indexeddb helps preserve changes locally and improves resilience during temporary connectivity issues.
  • Test real-world collaboration scenarios: Open multiple browser windows and simulate network delays to validate synchronization, cursor accuracy, undo/redo behavior, and reconnection handling.
  • Clean up resources properly: Always dispose of the provider and Y.Doc when the component unmounts to avoid lingering connections and stale awareness states.

Common issues and how to fix them

Even with a straightforward setup, a few common configuration issues can prevent collaboration features from working as expected.

Issue Possible cause Solution
Cursors don’t appear, and remote changes aren’t visible Awareness is disabled, or the selected provider doesn’t support awareness. Enable enableAwareness and verify that your provider supports awareness features.
Remote usernames are missing on cursors User information isn’t provided in the user’s configuration. Populate the user field for all participants, including the local user.
Changes sync locally but not across clients Clients are connected to different rooms or the provider is disconnected. Ensure all clients use the same room ID and verify the connection in the browser’s network panel.
Adapter or runtime imports fail The installed package version exposes APIs differently. Check the package documentation and installed type definitions. The collaboration adapter should provide yRuntime and yXmlFragment.
WebSocket connections disconnect frequently The server endpoint is unreachable or reconnect settings aren’t configured. Validate the WebSocket URL, enable provider retry options, and display connection status in the UI.

For more advanced troubleshooting and configuration details, refer to the official React Block Editor collaboration documentation.

Preparing for production

A collaborative editor that works locally isn’t always ready for real-world usage. Before deploying, consider the following:

  • Use secure WebSocket connections (wss://): Most browsers block unencrypted WebSocket connections in production environments.
  • Protect document access: Authenticate users and validate access to collaboration rooms using signed tokens or your existing identity system.
  • Add server-side rate limiting: This prevents a faulty or malicious client from overwhelming the collaboration channel.
  • Persist shared documents: Without persistence, recent edits can be lost if the server restarts. Solutions such as Hocuspocus with database storage or Yjs persistence adapters can help retain document state.
  • Capture operational telemetry: Track connection, disconnection, and error events to simplify troubleshooting.
  • Monitor connection health: A connection status indicator in the UI helps users understand when synchronization issues occur.
  • Load test early: Simulate multiple concurrent users to validate synchronization performance, cursor latency, and conflict resolution behavior.

Performance tips

As collaboration scales, a few optimizations can improve the user experience:

  • Disable awareness when needed: Presence updates are lightweight, but they still consume bandwidth. Consider disabling them in low-bandwidth environments.
  • Lazy-load the editor: In frameworks such as Next.js, dynamically loading the editor can improve initial page load times.
  • Optimize bundle size: Import only the components and modules you use to reduce the amount of JavaScript shipped to the browser.

Accessibility considerations

Collaboration features introduce accessibility requirements beyond the editor itself.

  • Announce presence changes: Use ARIA live regions so screen readers can notify users when collaborators join or leave.
  • Respect reduced-motion preferences: Apply prefers-reduced-motion to presence indicators and collaboration-related animations.
  • Maintain focus stability: Awareness updates should never unexpectedly move keyboard focus within the editor.

While the Block Editor follows WCAG 2.1 accessibility patterns, collaboration-specific experiences should also be reviewed as part of your application’s overall accessibility strategy.

Browser compatibility

Collaborative editing relies on web technologies that are widely supported in modern browsers:

  • y-websocket and Hocuspocus require WebSocket support, which is universal in modern browsers.
  • y-webrtc relies on WebRTC support available in current Chromium, Firefox, and Safari browsers.
  • y-indexeddb uses IndexedDB for local persistence and works across modern browsers that support progressive web applications.

Build Powerful Content Editing Experiences in React

From rich text editing and document formatting to media embedding and collaborative content creation, Syncfusion React Block Editor equips developers with everything needed to deliver modern, intuitive content authoring experiences.

Explore React Block Editor Features

Frequently Asked Questions

How does the React Block Editor handle simultaneous edits to the same block?

The React Block Editor uses Yjs CRDTs to synchronize changes. Edits to different blocks merge automatically, while concurrent edits at the same position are resolved deterministically. Undo and redo actions affect only the local user’s changes without impacting other collaborators.

Can I use the React Block Editor collaboration features without a backend?

Yes. For development and prototypes, you can use providers that require little or no backend infrastructure. For staging and production environments, a WebSocket-based provider is recommended for reliable synchronization and persistence.

How do I show who is currently editing a document?

Enable the enableAwareness property in the React Block Editor’s collaborationSettings, provide user details such as names and avatar colors, and set the local user’s ID. The editor automatically displays remote cursors and selections, while active user information can be retrieved from the provider’s awareness state.

Can I disable collaboration for certain documents?

Yes. Collaboration is optional. If you don’t configure collaborationSettings, the editor functions as a standard single-user editor.

Does collaboration affect performance?

Collaboration features are designed to be lightweight, but they do introduce additional network traffic. If user presence isn’t needed, disabling enableAwareness can help reduce overhead.

Can I switch providers later?

Yes. You can start with a provider such as y-webrtc during development and move to y-websocket or a managed service later. The shared Y.Doc and collaboration setup remain the same.

GitHub reference

For more details, refer to the example for real-time collaborative editing in React Block Editor using Yjs on the GitHub repository.

Bring real-time collaboration to your next React project

Building real-time collaboration means solving challenges such as synchronization, conflict resolution, and user presence. By combining the Syncfusion React Block Editor with Yjs, you can add these capabilities without building the collaboration layer from scratch.

Start with a local y-websocket server, connect multiple clients, and see how edits, cursors, and document updates stay synchronized in real-time. As your application grows, you can extend the same foundation with authentication, persistence, and production-scale infrastructure.

Ready to explore collaborative editing in your own application? Check out the resources below:

Read the whole story
alvinashcraft
34 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories