Back to articles

Building a Real-Time Collaborative Text Editor with Svelte and WebSocket

AuthorMajd Muhtaseb05/13/202510 minutes
Building a Real-Time Collaborative Text Editor with Svelte and WebSocket

Introduction

This article demonstrates how to create a basic real-time collaborative text editor using Svelte for the user interface and WebSocket for handling real-time communication between users. We'll cover the fundamental concepts and provide code snippets to get you started.

Setting up the Svelte Project

First, initialize a new Svelte project using your preferred method (e.g., degit sveltejs/template my-editor).

Frontend (Svelte)

Here's a simplified App.svelte component:

<script>
  import { onMount } from 'svelte';

  let text = '';
  let socket;

  onMount(() => {
    socket = new WebSocket('ws://localhost:8080'); // Replace with your WebSocket server URL

    socket.onopen = () => {
      console.log('WebSocket connection established');
    };

    socket.onmessage = (event) => {
      text = event.data;
    };

    socket.onclose = () => {
      console.log('WebSocket connection closed');
    };
  });

  function handleInput() {
    if (socket && socket.readyState === WebSocket.OPEN) {
      socket.send(text);
    }
  }
</script>

<textarea bind:value={text} on:input={handleInput} rows="20" cols="60"></textarea>

Explanation:

  • onMount: Establishes the WebSocket connection when the component mounts.
  • socket.onmessage: Updates the text variable whenever a message is received from the server.
  • handleInput: Sends the current text content to the server whenever the textarea's content changes.
  • bind:value: Two-way binding between the text variable and the textarea.

Backend (Node.js with WebSocket)

Here's a simple Node.js WebSocket server (using the ws library):

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

let connectedClients = new Set();

wss.on('connection', ws => {
  console.log('Client connected');
  connectedClients.add(ws);

  ws.on('message', message => {
    connectedClients.forEach(client => {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message.toString());
      }
    });
  });

  ws.on('close', () => {
    console.log('Client disconnected');
    connectedClients.delete(ws);
  });
});

console.log('WebSocket server started on port 8080');

Explanation:

  • The server listens for incoming WebSocket connections.
  • When a client connects, it's added to the connectedClients set.
  • When the server receives a message from a client, it broadcasts that message to all other connected clients (excluding the sender).
  • When a client disconnects, it's removed from the connectedClients set.

To install the ws library, run: npm install ws. Save this as server.js and run using node server.js.

Running the Application

  1. Start the Node.js WebSocket server (node server.js).
  2. Run the Svelte development server (npm run dev in the Svelte project).
  3. Open multiple browser windows pointing to your Svelte application's URL.
  4. As you type in one window, the text will update in the other windows in real-time.

Conclusion

This is a basic example, but it illustrates the core principles of building a real-time collaborative text editor using Svelte and WebSocket. You can extend this example by adding features like user authentication, rich text formatting, and undo/redo functionality.