DEV Community

Cover image for How to Build a Live Code Editor for Coding Interviews with Node.js, React, and Socket.IO
Ghazi Khan
Ghazi Khan

Posted on • Originally published at ghazikhan.in

How to Build a Live Code Editor for Coding Interviews with Node.js, React, and Socket.IO

Conducting technical interviews often requires a real-time coding environment to assess candidates. While many platforms offer complete solutions, sometimes you need something simpler—an editor that focuses solely on live collaboration without the need to run or test code. In this tutorial, I'll walk you through building a live code editor tailored for coding interviews, using Node.js, React, Socket.IO, and the Monaco Editor.

Why Build a Live Code Editor?

The primary goal of this project is to create a real-time collaborative environment where interviewers and candidates can code together seamlessly. No need for running code or complicated setup—just a clean interface for typing and reviewing code in real-time.

We’ll be using a powerful set of tools:

  • Node.js for the backend to manage real-time connections.
  • React.js for the frontend to build an interactive user interface.
  • Socket.IO for real-time communication between users.
  • Monaco Editor, the same code editor that powers Visual Studio Code, for a smooth coding experience.

By the end of this tutorial, you'll have a fully functional live code editor ready for conducting coding interviews.

Features of the Live Code Editor

  • Users can create interview rooms by specifying a room name.
  • Each room gets a unique room ID generated using crypto.
  • The room ID is used to connect users to the Socket.IO room for live code collaboration.
  • The editor provides real-time synchronization so that everyone in the room can see updates instantly.

Tech Stack Overview

  • Backend: Node.js, Socket.IO, MongoDB
  • Frontend: React.js, Monaco Editor, Axios, Tanstack Router, ShadCN UI, TailwindCSS

Getting Started

Before diving into the code, make sure you have the following installed:

  1. Node.js (v14 or later)
  2. MongoDB (for storing room data)
  3. React (v17 or later)
  4. Socket.IO (v4 for real-time collaboration)
  5. Monaco Editor (for the live code editing experience)
  6. TailwindCSS (for styling)
  7. Tanstack Router (for handling routes)

Video Tutorial if you don't like to read complete blog

Step 1: Setting Up the Backend with Node.js and Socket.IO

To handle real-time collaboration, we need to set up a Socket.IO server. Start by creating a new Node.js project and installing the necessary dependencies.

mkdir live-code-editor
cd live-code-editor
npm init -y
npm install express socket.io crypto mongoose
Enter fullscreen mode Exit fullscreen mode

Now, create a basic server that will handle Socket.IO connections and serve the React frontend.

// server.js
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const crypto = require('crypto');
const mongoose = require('mongoose');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

// MongoDB setup for room data
mongoose.connect('mongodb://localhost/live-editor', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
});

// Room schema for MongoDB
const RoomSchema = new mongoose.Schema({
    roomId: String,
    roomName: String,
});

const Room = mongoose.model('Room', RoomSchema);

// Socket.IO connection handling
io.on('connection', (socket) => {
    console.log('New client connected');

    socket.on('joinRoom', ({ roomId }) => {
        socket.join(roomId);
    });

    socket.on('codeUpdate', ({ roomId, code }) => {
        socket.to(roomId).emit('codeUpdate', code);
    });

    socket.on('disconnect', () => {
        console.log('Client disconnected');
    });
});

app.get('/', (req, res) => {
    res.send('Server is running...');
});

server.listen(5000, () => {
    console.log('Server is running on port 5000');
});
Enter fullscreen mode Exit fullscreen mode

In this code, we:

  1. Create a basic Express server.
  2. Use Socket.IO to handle real-time communication between the interviewer and the interviewee.
  3. Generate unique room IDs using crypto.
  4. Store room data in MongoDB.

Step 2: Building the Frontend with React and Monaco Editor

Next, let’s set up the React frontend. This will include a text editor powered by Monaco Editor, real-time updates using Socket.IO, and routing for different rooms.

npx create-react-app live-code-editor-client
cd live-code-editor-client
npm install socket.io-client monaco-editor axios tanstack/react-router@latest shadcn-ui tailwindcss
Enter fullscreen mode Exit fullscreen mode

Configure TailwindCSS in your project for styling. Then, build out the main components:

Room Creation Component

Allow users to create a new interview room and generate a unique room ID.

import React, { useState } from 'react';
import axios from 'axios';

const CreateRoom = () => {
    const [roomName, setRoomName] = useState('');

    const createRoom = async () => {
        const roomId = crypto.randomUUID();
        await axios.post('/api/create-room', { roomName, roomId });
        window.location.href = `/room/${roomId}`;
    };

    return (
        <div>
            <h1>Create a New Interview Room</h1>
            <input
                type="text"
                value={roomName}
                onChange={(e) => setRoomName(e.target.value)}
                placeholder="Enter Room Name"
            />
            <button onClick={createRoom}>Create Room</button>
        </div>
    );
};

export default CreateRoom;
Enter fullscreen mode Exit fullscreen mode

Room Component for Live Code Collaboration

This component will handle the live code collaboration using Socket.IO and Monaco Editor.

import React, { useEffect, useState } from 'react';
import { io } from 'socket.io-client';
import MonacoEditor from 'react-monaco-editor';
import { useParams } from '@tanstack/react-router';

const Room = () => {
    const { roomId } = useParams();
    const [code, setCode] = useState('');
    const socket = io('http://localhost:5000');

    useEffect(() => {
        socket.emit('joinRoom', { roomId });

        socket.on('codeUpdate', (newCode) => {
            setCode(newCode);
        });

        return () => {
            socket.disconnect();
        };
    }, [roomId]);

    const handleEditorChange = (newValue) => {
        setCode(newValue);
        socket.emit('codeUpdate', { roomId, code: newValue });
    };

    return (
        <div className="editor-container">
            <MonacoEditor
                language="javascript"
                value={code}
                onChange={handleEditorChange}
                theme="vs-dark"
                height="500px"
            />
        </div>
    );
};

export default Room;
Enter fullscreen mode Exit fullscreen mode

Step 3: Implementing Socket.IO on Frontend

Ensure Socket.IO is integrated properly on the frontend to handle real-time updates. The editor's state is updated on both ends as users type.

socket.on('codeUpdate', (newCode) => {
    setCode(newCode);
});
Enter fullscreen mode Exit fullscreen mode

Every time the code changes, it's sent to the backend using:

socket.emit('codeUpdate', { roomId, code: newValue });
Enter fullscreen mode Exit fullscreen mode

Step 4: Styling the App with TailwindCSS

Use TailwindCSS to make the app look clean and responsive. Ensure the layout allows for a good coding experience during interviews.

Conclusion

You've now built a fully functional live code editor tailored for coding interviews using Node.js, React, and Socket.IO. This tool allows interviewers and candidates to collaborate on code in real-time, making it easier to assess coding skills without the need for extra features like running or compiling code. By focusing on real-time collaboration, we’ve created a lightweight and highly effective solution for coding interviews.


Subscribe to Newsletter: https://codewithghazi.substack.com

Top comments (0)