Collaborative Whiteboard Implementation for Your Website

Collaborative Whiteboard Implementation for Your Website

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1281
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1237
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    977
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1025
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1103
  • image_website-_0.webp
    Website development for Red Pear
    550

Collaborative Whiteboard Implementation for Your Website

Synchronizing changes during collaborative board editing is one of the toughest challenges in web development. Without the right rendering stack and sync mechanism, your project risks bugs and poor performance. We build online whiteboards for team collaboration: freehand drawing, sticky notes, shapes, lines, and real-time sync. Our engineers implement whiteboards from scratch or integrate existing SDKs (tldraw, Excalidraw) with custom CRDT synchronization. Over 30 projects delivered—from simple note boards to full collaborative editors with WebRTC and audio calls. Teams using our approach save up to 40% development time compared to building in-house.

Choosing the Right Rendering Stack

Option Time to MVP Customizability Performance (1000 shapes) Maintenance Cost
tldraw 1–2 days Medium (SDK) High (Canvas) Low (open-source)
Konva.js 3–4 weeks Full High (Canvas) Medium
Excalidraw 1–2 days (fork) Low (fork is complex) Medium (SVG) High (fork)
Fabric.js 2–3 weeks Medium Medium (Canvas) High (aging)
SVG + vanilla 1–2 weeks Full Low at >500 shapes Medium

For a production product with custom requirements, we prefer tldraw as a base or Konva.js from scratch. Excalidraw forks are possible but the maintenance overhead is high. We select the stack based on your use case and budget.

Why CRDT Is Optimal for Sync

CRDT (Conflict-free Replicated Data Type) automatically resolves edit conflicts without a central server. For whiteboards we use Yjs, a CRDT library optimized for collaborative editing. Yjs is up to 3× faster than OT (Operational Transformation) in benchmarks with 10 concurrent users—a real difference when editing a busy board.

Architecture: Board State

A board is a collection of shape objects. Each shape has a type, geometry, and style.

Common Shape Types
Type Properties
Rect x, y, width, height, fill, stroke, strokeWidth, cornerRadius
Ellipse x, y, radiusX, radiusY, fill, stroke
Line points, stroke, strokeWidth
Arrow points, stroke, headStyle
Text content, fontSize, fontFamily, color, width
Freehand points, stroke, strokeWidth, pressure
Image src, x, y, width, height

CRDT for Shape Sync

Y.Map is perfect for storing each shape by its id:

import * as Y from 'yjs'; import { WebsocketProvider } from 'y-websocket'; const ydoc = new Y.Doc(); const yshapes = ydoc.getMap<Y.Map<unknown>>('shapes'); const provider = new WebsocketProvider( process.env.WS_URL!, `board-${boardId}`, ydoc ); // Add a shape function addShape(shape: Shape) { const yshape = new Y.Map<unknown>(Object.entries(shape)); yshapes.set(shape.id, yshape); } // Update (e.g., on drag) function updateShape(id: string, patch: Partial<Shape>) { const yshape = yshapes.get(id); if (!yshape) return; ydoc.transact(() => { Object.entries(patch).forEach(([key, value]) => { yshape.set(key, value); }); }); } // Delete function deleteShape(id: string) { yshapes.delete(id); } // Reactivity yshapes.observeDeep((events) => { events.forEach((event) => { rerenderCanvas(yshapes); }); }); 

Freehand Drawing: Point Optimization

Freehand drawing generates hundreds of points. Sending all of them is expensive. We use the Ramer-Douglas-Peucker algorithm to simplify the curve:

function rdp(points: [number, number][], epsilon: number): [number, number][] { if (points.length < 3) return points; let maxDist = 0; let maxIdx = 0; const end = points.length - 1; for (let i = 1; i < end; i++) { const dist = perpendicularDistance(points[i], points[0], points[end]); if (dist > maxDist) { maxDist = dist; maxIdx = i; } } if (maxDist > epsilon) { const left = rdp(points.slice(0, maxIdx + 1), epsilon); const right = rdp(points.slice(maxIdx), epsilon); return [...left.slice(0, -1), ...right]; } return [points[0], points[end]]; } 

After the user finishes drawing, we run simplification and sync the reduced point set. For smooth curves, we rely on the perfect-freehand library.

Viewport: Pan and Zoom

Our board uses an infinite canvas. All coordinates are in world space; the viewport defines what is visible:

interface Viewport { x: number; // offset y: number; zoom: number; // 0.1 – 4.0 } // World coordinates → screen function worldToScreen(wx: number, wy: number, vp: Viewport) { return { x: wx * vp.zoom + vp.x, y: wy * vp.zoom + vp.y, }; } // Screen → world (for pointer events) function screenToWorld(sx: number, sy: number, vp: Viewport) { return { x: (sx - vp.x) / vp.zoom, y: (sy - vp.y) / vp.zoom, }; } // Zoom to a point (pinch or scroll wheel) function zoomAt(vp: Viewport, screenX: number, screenY: number, delta: number): Viewport { const factor = delta > 0 ? 1.1 : 0.9; const newZoom = Math.max(0.1, Math.min(4.0, vp.zoom * factor)); const zoomRatio = newZoom / vp.zoom; return { x: screenX - (screenX - vp.x) * zoomRatio, y: screenY - (screenY - vp.y) * zoomRatio, zoom: newZoom, }; } 

Canvas vs SVG: Choosing Under Load

Below 500 shapes, SVG works perfectly and simplifies hit-testing. Above 1000 shapes with active drawing, we switch to Canvas (2D) or WebGL via Pixi.js. A hybrid approach renders shapes on Canvas and UI elements in HTML on top.

Concrete Case: Ed-Tech Platform

For an ed-tech client, we built a collaborative whiteboard used by teachers and students. We chose tldraw for rapid prototyping, then replaced its sync layer with Yjs to handle up to 30 concurrent users. The result: sync latency dropped from ~200 ms to under 50 ms, and the board remained responsive even with 500+ shapes. The project went from design to production in 10 days.

Undo / Redo Implementation

Yjs provides an UndoManager that groups operations across a 500 ms window:

const undoManager = new Y.UndoManager(yshapes, { trackedOrigins: new Set([ydoc.clientID]), captureTimeout: 500, }); document.addEventListener('keydown', (e) => { if (e.ctrlKey && e.key === 'z') undoManager.undo(); if (e.ctrlKey && e.key === 'y') undoManager.redo(); }); 

Board Export to PNG

async function exportToPNG(boardId: string): Promise<Blob> { const canvas = document.getElementById('whiteboard-canvas') as HTMLCanvasElement; const shapes = Array.from(yshapes.values()).map(s => shapeFromYMap(s)); const bbox = getBoundingBox(shapes); const offscreen = new OffscreenCanvas(bbox.width + 80, bbox.height + 80); const ctx = offscreen.getContext('2d')!; ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, offscreen.width, offscreen.height); renderShapes(ctx, shapes, { x: -bbox.x + 40, y: -bbox.y + 40, zoom: 1 }); return await offscreen.convertToBlob({ type: 'image/png' }); } 

Our Work Process

  1. Analysis: Understand user scenarios, pick the right stack.
  2. Design: Data architecture, sync protocol, UI layout.
  3. Implementation: Build canvas engine, integrate Yjs, create custom tools.
  4. Testing: Unit tests, load testing, sync validation across users.
  5. Deployment: Docker image, WebSocket setup, CDN for static assets.

Timeline Estimates

  • Integrate tldraw with custom Yjs sync: 5–7 days.
  • Full whiteboard from scratch (Konva.js + freehand, shapes, viewport, undo, presence, export): 3–4 weeks.
  • Add WebRTC for video/audio alongside the board: +1 week.
  • All code comes with a one-month free bug-fix warranty.

What's Included

  • Architectural documentation (stack choice, data schema, sync protocol).
  • Full source code of the board with comments and critical module tests.
  • Integration with your authentication system and API.
  • Deployment (Docker image, WebSocket config, CDN).
  • Team workshop on customization and maintenance.
  • One-month free bug-fix guarantee.
  • Certified engineers with deep experience in real-time collaboration.

Get a free consultation from our engineers—we'll assess your project and propose the optimal solution. Contact us to discuss the details.