Real-Time Collaboration in MiN8T: A Tour of the Six Indicators
Two teammates sit in different cities, both looking at the same template in their browser. One of them starts typing into a headline. The other one sees every keystroke appear on their canvas, watches a colored border bloom around that block, and sees a tiny circle with their colleague's initials pinned to its corner. In the footer it reads: Typing: Alex. That's what this article is about.
MiN8T now ships a complete set of real-time collaboration indicators for the email editor: live cursors, block locks, typing indicators, canvas sync, presence avatars, and real-time comments. Every one of them is independently toggleable from your workspace settings. This guide walks through what each indicator means, how to use it, when to turn it off, and what's happening on the wire.
Who this is for: Anyone editing templates with a teammate — product marketers, design-ops, agencies, and enterprise teams coordinating across offices. You don't need to know anything about WebSockets to use this; the "under the hood" section is here for the curious.
1 What just shipped
If you opened the editor six months ago, you saw a presence-avatar row in the top-right corner showing who else was on the template, and a connection-status dot at the bottom. That was it. Two people on the same template couldn't see each other's cursors, couldn't tell who was editing which block, and wouldn't know the other person had changed something until they saved and you reloaded.
Here's what changed:
Presence avatars
Colored circle with initials for every teammate currently on the template, in the toolbar.
Live cursors
A pointer with each teammate's name flag, tracking their mouse in real time across the canvas.
Block locks
Colored border + initials badge on any block a teammate is currently editing. You can't overwrite them.
Typing indicator
Footer reads "Typing: Alex" whenever a teammate has a block selected. Their avatar pulses green.
Live canvas sync
Content and style changes flow across tabs in roughly 300–700 ms. No one needs to reload.
Real-time comments
A comment, reply, resolve, or reopen made in one window appears everywhere else without reload.
The combination is what most people mean when they say "multiplayer email editing." It's the same mental model you use in Figma, Google Docs, or Notion — you can see who's with you, what they're looking at, and what they're changing, as it happens.
2 The six indicators, one by one
Presence avatars
A row of small colored circles sits to the left of the Code / Visual toggle in the top toolbar. One circle per teammate currently in the template. Each circle shows initials from their display name and uses their assigned user color — the same color you'll see on their cursor, their block locks, and anywhere else they're represented. Hover over a circle and the tooltip gives you their full name.
When more than eight people are on the template at once, the row collapses into a +N more overflow badge so the toolbar doesn't blow up horizontally.
Live cursors
Move your mouse over the canvas. Everyone else in the template sees your cursor as a colored arrow with your name attached, tracking where you move. The cursor fades quietly after five seconds of not moving so idle cursors don't clutter a busy workspace, and snaps back to full opacity the moment you move again.
Mouse position is sent roughly 20 times per second — enough for the motion to feel continuous, not so often that your network fills with cursor packets. This matches what Figma's multiplayer writeup describes for their cursor tracking, and what industry-standard libraries like Liveblocks default to.
Block locks
Click into any block on the canvas — a text block, an image, a button, anything. What changes visually for you: nothing obvious. What changes for everyone else: a 2-pixel colored border appears around that block, with a small circle in the top-left corner showing your initials. Hover the circle and a dark tooltip reads Editing: Your Name.
While you hold that block, other teammates cannot select or edit it. If they click it, they get a toast that reads "{you} is editing this block" and the selection is refused. The lock follows you as you click from block to block, and releases automatically when you deselect or close the tab.
Why the top-left corner? Comment pins already live at the top-right. Putting both on the same corner would mean your comment indicator could be hidden by a teammate's lock badge. Separating them keeps both visible on the same block.
Typing indicator
Typing is derived from block-lock state — the logic is simply "a teammate holding a block is actively editing." Two things change when that's true: a green ring pulses around that teammate's presence avatar in the toolbar, and the status bar at the bottom of the editor updates to read ••• Typing: Alex. Multiple concurrent editors read as Typing: Alex, Morgan.
We deliberately don't do per-keystroke typing indicators. Short bursts of typing trigger flickery indicators that distract more than they inform, which is why Google Docs doesn't show them either — the live cursor and live text rendering already tell you someone is typing.
Live canvas sync
When you edit anything — text content, image swap, color, alignment, block reorder, insertion, deletion — your change reaches everyone else on the template within 300–700 ms, without anyone reloading. Every content change goes through a 300 ms debounce so rapid edits get batched into one network send; text typing adds another 400 ms batch on top of that so keystroke bursts don't hit the wire one at a time.
The model is last-write-wins: if two editors change the same property at the same time, whichever change the server sees last is the one that sticks. For the typical case of "one person typing at a time," this is invisible and correct. We do not currently attempt operational transformation or CRDT-style merge on conflicting simultaneous edits of the same block — that's a deliberate tradeoff we revisit below.
Real-time comments
Drop a comment pin on a block. Anyone else on the template sees the pin appear instantly, with a red unread dot next to its count. Reply to a thread, mark it resolved, reopen it, edit the text — every action propagates live to every viewer. No reload, no "pull to refresh," no polling.
Comment sync is wired through the same WebSocket channel as everything else, so if you're connected you're in sync on comments by definition.
3 What you'll see on the canvas
A quick visual summary of where each indicator lives:
| Indicator | Where it renders | When it shows |
|---|---|---|
| Presence avatars | Top toolbar, left of Code/Visual toggle | Always, for everyone on the template |
| Live cursors | Floats over the canvas at viewport coordinates | While teammates move their mouse; fades after 5s idle |
| Block locks | Colored border + initials badge top-left of any locked block | While a teammate has that block selected |
| Typing indicator | Status bar at bottom; pulse ring on toolbar avatar | While a teammate holds a block lock |
| Live canvas sync | The canvas itself — content/style changes arrive silently | 300–700 ms after any peer edit |
| Real-time comments | Pins on blocks + comments panel | Instantly on create/reply/resolve/edit |
4 How it actually works under the hood
You don't need to know any of this to use the feature, but if you're curious or if you're troubleshooting something unexpected, here's the shape of it.
The transport: one WebSocket per template room
When you open a template, the editor opens a WebSocket to our collaboration service at wss://api.min8t.com/collaboration/ws/collaborate and joins a "room" keyed by the template ID. Every client in the room is a peer; every broadcast from any client is relayed to every other client in the same room. Join/leave, cursor movement, block locks, text snapshots, comment events — all of it flows over that one connection.
This is the same pattern Figma describes for their multiplayer technology, and the one Liveblocks, PartyKit, and similar infrastructure providers normalize as "rooms." It's the de-facto transport for browser-based multiplayer.
Sync model: server-arbitrated last-writer-wins snapshots
When you edit anything, your editor builds a fresh copy of the template JSON and sends it to the server. The server broadcasts that snapshot to every other client in the room (not back to you). Each receiver replaces their local template with the received one and re-renders. The template model itself is hierarchical (stripes → containers → blocks), so a snapshot sync is cleaner than trying to express every possible mutation as a discrete operation.
This is deliberately simpler than Operational Transformation (OT) or CRDT-based merge. OT requires a transformation matrix for every operation type you support — and our template has dozens of per-block properties, plus nesting. CRDTs add significant per-operation metadata overhead, especially for rich content. For our use case — teams that coordinate who edits which block, rather than two people racing on the same character — the snapshot model is correct and simple.
Related reading: For a deeper comparison of OT vs CRDT vs snapshot sync, Evan Wallace's post "How Figma's multiplayer technology works" is the canonical writeup; Figma themselves chose neither OT nor CRDT for reasons that closely mirror ours.
Cursor and presence: throttled + ephemeral
Cursor events are debounced to roughly 50 ms (20/second) on the sender, and rendered with a 100 ms CSS transition on receivers so the motion reads as smooth rather than jumpy. Presence events (join, leave, active user list) are not throttled — they fire once per state change.
Cursor and presence events are ephemeral: we don't persist them. If you reload, you start fresh. Only document state (the template itself, comments) is persisted.
Heartbeats and reconnection
The WebSocket sends a ping every 25 seconds. If the connection drops, the client auto-reconnects with exponential backoff and rejoins the room. On rejoin, you receive the current room state (active users + current template snapshot) so you're immediately in sync.
Block locks are Redis-backed
When you claim a lock on a block, the server records it in Redis with a 5-minute TTL. Your client refreshes the TTL every 20 seconds for as long as you hold the lock. If you close your tab without releasing, the lock expires at the TTL mark and other users can acquire it. Same-user multi-tab is allowed — your own lock refreshes cleanly from any tab you have open — but a peer trying to acquire your lock gets rejected.
5 Turning features on and off
Every one of the six indicators is a workspace-level toggle. Not every team wants every feature on all the time — presence is distracting during focused design sprints, cursors can be noisy in a screen-share, and some compliance-sensitive industries need edit history without peer awareness. Here's how to find them:
- Open the dashboard and navigate to Workspace Settings → Features (owner role required).
- You'll see a Collaboration Indicators card, collapsed by default. The card header shows a summary like "4 of 5 enabled" so you know the state at a glance.
- Click the card to expand. Five toggles appear: Presence Avatars, Live Cursors, Block Locks, Live Canvas Sync, and Typing Indicator.
- Flip any toggle. Changes take effect on the next editor load (reload an open editor tab to see the change).
A few patterns we've seen teams use:
- Legal / compliance teams: Block Locks on, everything else off. Reviewers can see who changed what in audit logs; they don't need real-time peer awareness.
- Design-heavy agencies: Everything on. Cursors + typing + live sync is close to a Figma-like experience and matches how their design-tool workflows already function.
- Single-user accounts: Presence Avatars off (no peers means the row is empty anyway), Live Canvas Sync on (safe default for the day they add a teammate).
- Focused sprint mode: Live Cursors off temporarily when a team wants to get heads-down work done without watching each other's mouse pointers.
Note on dependencies: The Typing Indicator derives from Block Locks. If you turn Block Locks off, Typing has no data to read and won't show anything regardless of its own toggle. This is intentional — it keeps the data flow simple.
6 Working-style recommendations
Real-time collaboration sounds uniformly great until you're on your fourth call of the day with six people moving their cursors around the same canvas. Here are patterns that have worked for teams we've talked to.
Don't leave all six on by default for every workspace
If your team is a single designer plus occasional stakeholders dropping in to review, you probably want Presence + Comments, and everything else off. The indicators have a cognitive cost — every colored circle you see is a tiny task-switch asking you "who is that, what are they doing?" Enable only what your actual workflow needs.
Use block locks as a social contract, not a technical one
Block locks stop simultaneous edits on the same block. They don't stop you and a teammate from both rearranging the header in alternating edits. If your team is producing time-sensitive campaigns with multiple editors, have a rough convention — one person owns copy, one owns imagery, one owns branding — and let the indicators give you feedback rather than enforcement.
Resolve comment threads aggressively
Real-time comments make it very cheap to drop a quick note. That's a feature. The failure mode is that unresolved threads pile up. Resolve threads as you address them; use the comment panel's "Resolved" filter to archive old context without deleting it.
Turn things off during screen-shares
Screen-sharing an editor with cursors on means your audience watches your mouse movements plus any collaborator's movements. Before a demo, we recommend temporarily disabling Live Cursors at the workspace level. It takes five seconds and your demo is cleaner.
7 Accessibility & focus considerations
The indicators respect a few accessibility defaults. If you'd like us to extend any of these, let us know — accessibility is an ongoing commitment, not a one-time ship.
- Reduced motion: The typing-avatar pulse animation respects
prefers-reduced-motion— if you've opted into reduced motion at the OS level, the avatar simply stays green without pulsing. - Color isn't the only cue: Every indicator that uses a per-user color also includes initials or a name label. Colorblind users see the same identity information.
- Keyboard access: You can tab to any block on the canvas, which triggers block-lock acquisition normally. Presence avatars expose hover tooltips for mouse users; screen readers read the user's display name from the
titleattribute. - Screen-reader announcements: Presence changes (teammate joined / left) are not currently announced to screen readers as
aria-liveupdates. This is a known gap we plan to address.
Focus mode: The per-feature toggles in Workspace Settings give you the equivalent of a focus mode — turn off Cursors + Typing to get a quieter canvas without losing the other collaboration affordances. We're tracking whether teams want a per-user focus toggle rather than a per-workspace one.
Try it with a teammate
Open any template, send the link to a colleague, and watch what happens when you both hit the canvas.
Get Started Free