Graphics Engineering

Collaborative 3D Editing: Yjs meets Three.js for Spatial Design

Step-by-step guide to building collaborative 3D environments in 2026. Use Yjs and Three.js to sync state in real-time.

Sachin Sharma
Sachin SharmaCreator
Apr 16, 2026
2 min read
Collaborative 3D Editing: Yjs meets Three.js for Spatial Design
Featured Resource
Quick Overview

Step-by-step guide to building collaborative 3D environments in 2026. Use Yjs and Three.js to sync state in real-time.

Collaborative 3D Editing: Yjs meets Three.js for Spatial Design

In 2026, design is no longer a solitary activity. Whether it's architecting a metaverse environment or prototyping a physical product, teams expect to work in a shared 3D space with zero latency.

Today, we'll combine the power of Three.js (for rendering) with Yjs (for state synchronization).

The Challenge of 3D State

A 3D scene is not just text. It involves:

  • Object Transforms: Position, Rotation, Scale (Vector3/Euler).
  • Material Properties: Colors, Roughness, Metalness.
  • Hierarchy: The scene graph itself.
  • User Presence: Cursors, avatars, and current selection.

Architecting the Sync Layer

We use a shared Y.Doc to store the scene tree. Each 3D object in the Three.js scene corresponds to a Y.Map in the document.

javascript
import * as Y from 'yjs'; import { WebrtcProvider } from 'y-webrtc'; const doc = new Y.Doc(); const provider = new WebrtcProvider('room-2026', doc); const sceneMap = doc.getMap('scene'); // When an object is moved in Three.js function onObjectTransform(id, position) { const objMap = sceneMap.get(id); objMap.set('position', { x: position.x, y: position.y, z: position.z }); } // Observe changes and update local scene sceneMap.observeDeep((events) => { events.forEach(event => { const object3D = myThreeScene.getObjectByName(event.target.parent.get('id')); updateTransform(object3D, event.target.get('position')); }); });

Optimizing for 60fps Sync

Sending every micro-update of a drag operation can saturate the network.

  • Debouncing: Only send the final transform on "drag-end" or throttle updates to 20Hz.
  • Interpolation: On the receiving side, don't just snap the object to the new position. Use Lerp (Linear Interpolation) to smoothly animate it.
javascript
// Smooth interpolation on receive function animate() { cube.position.lerp(targetPositionFromYjs, 0.1); renderer.render(scene, camera); }

Cursor Presence in 3D Space

We represent other users as ray-casts or 3D avatars. By syncing the camera.matrix, we can even see exactly what our collaborators are looking at in the spatial environment.

Conclusion

The web is the only platform that truly enables frictionless, cross-platform collaboration. By mastering Yjs and Three.js, you are building the creative engines of the 2026 spatial web.

Sachin Sharma

Sachin Sharma

Software Developer & Mobile Engineer

Building digital experiences at the intersection of design and code. Sharing weekly insights on engineering, productivity, and the future of tech.