[TERMINAL · SKILLS]
> mounting /skills...
> indexing skill manifests...
> linking agents: claude · codex · gemini · cursor
> ready.
[░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
Use Cases/Build a Real-Time Collaborative Code Editor

Build a Real-Time Collaborative Code Editor

Build a browser-based code editor where multiple developers edit simultaneously with syntax highlighting, cursor presence, and live execution — powering pair programming and coding interviews.

Development#typescript#tsconfig#type-checking#type-safety#javascript-migration
Works with:claude-codeopenai-codexgemini-clicursor

Skills stack · 7 skills

Avg quality 94/100·All SAFE
>

typescript

v1.0.0

Sets up and repairs TypeScript projects: picks tsconfig.json settings for a Node.js service, an npm library or a bundled web app, runs type-checking in CI, and replaces `any` and unsafe casts with types the compiler can verify. Use when someone asks to "set up TypeScript", "fix this tsconfig", "fix a TypeScript error", "upgrade to TypeScript 6 or 7", "migrate JavaScript to TypeScript", "publish types for a package", "run .ts files in Node" or "make this type-safe". Covers the changed defaults in TypeScript 6.0 and 7.0, module and moduleResolution, strict mode, project references, declaration output, narrowing, satisfies and common compiler errors.

93/100 quality
7.30× impact
SAFE· stale score
View skill
>

yjs

v1.1.0

Yjs is a high-performance CRDT (Conflict-free Replicated Data Type) framework for building collaborative applications: shared types whose concurrent edits merge automatically. Use when a user asks to add real-time collaborative editing, shared cursors and presence, offline-first sync, or peer-to-peer collaboration to an app, to run or secure a y-websocket server, to persist Yjs documents, or to make a Tiptap or ProseMirror editor collaborative.

87/100 quality
2.16× impact
SAFE· stale score
View skill
>

hono

v1.1.0

Hono is a small web framework built on Web Standards (Request/Response) that runs unchanged on Cloudflare Workers, Deno, Bun, Node.js, AWS Lambda and Vercel. Use it when the user asks to build a Hono API, add Zod validation, JWT auth, CORS or middleware, use the type-safe RPC client (hc), render JSX, stream responses, or deploy one codebase to several runtimes.

100/100 quality
6.20× impact
SAFE· stale score
View skill
>

redis

v1.1.0

Redis is an in-memory data store used as a cache, session store, message broker and counter service. Use when adding a cache layer, storing sessions, rate limiting an API, running pub/sub or Streams with consumer groups, taking a distributed lock, building a leaderboard, or configuring Redis for production (persistence, maxmemory, eviction).

93/100 quality
1.79× impact
SAFE· stale score
View skill
>

docker-helper

v1.1.0

Build, debug, and optimize Docker configurations. Use when a user asks to create a Dockerfile, fix Docker build errors, optimize image size, write docker-compose files, debug container issues, set up multi-stage builds, or troubleshoot networking between containers. Covers Dockerfile best practices and compose orchestration.

100/100 quality
1.44× impact
SAFE· stale score
View skill
>

e2b

v1.1.0

E2B is a cloud platform that gives AI agents secure, isolated sandboxes — ephemeral Linux VMs with a filesystem, package managers, and internet access — to run AI-generated code safely. Use when a user wants an agent to execute Python or JavaScript, install packages, read/write files, or run a long process without risking the host machine, or wants to wire code execution into a LangChain, CrewAI, or custom agent loop.

93/100 quality
1.54× impact
SAFE· stale score
View skill
>

zod

v1.1.0

Zod is a TypeScript-first schema library that validates data at runtime and infers static types from the same schema. Use when validating API request bodies, form input, environment variables or config files, parsing untrusted JSON, or migrating from Zod 3 to Zod 4. Covers z.object, safeParse, z.infer, coercion, discriminated unions, refinements, JSON Schema output and the v4 API changes.

93/100 quality
3.87× impact
SAFE· stale score
View skill
$

The Problem

A coding interview platform uses a basic textarea for candidates to write code. No syntax highlighting, no auto-complete, and no way for the interviewer to see the candidate's code in real-time — they share screens on Zoom and the interviewer can't type. When two interviewers join, they take turns dictating edits. The platform also wants pair programming features for its learning product, but the current architecture can't support real-time collaboration.

Step 1: CRDT-Backed Document Sync

typescript
// src/editor/document.ts
import * as Y from 'yjs';

export function createCodeDocument(): {
  doc: Y.Doc;
  getText: () => Y.Text;
  getLanguage: () => Y.Map<string>;
  getMetadata: () => Y.Map<any>;
} {
  const doc = new Y.Doc();

  return {
    doc,
    getText: () => doc.getText('code'),
    getLanguage: () => doc.getMap('language'),
    getMetadata: () => doc.getMap('metadata'),
  };
}

// Awareness: cursor positions and selections
export interface EditorAwareness {
  userId: string;
  userName: string;
  color: string;
  cursor: {
    lineNumber: number;
    column: number;
  } | null;
  selection: {
    startLineNumber: number;
    startColumn: number;
    endLineNumber: number;
    endColumn: number;
  } | null;
}

Step 2: WebSocket Sync Server

typescript
// src/editor/sync-server.ts
import { Hono } from 'hono';
import * as Y from 'yjs';
import { Redis } from 'ioredis';

const redis = new Redis(process.env.REDIS_URL!);

// In-memory document store (per room)
const rooms = new Map<string, {
  doc: Y.Doc;
  connections: Set<WebSocket>;
  awareness: Map<string, any>;
}>();

function getOrCreateRoom(roomId: string): typeof rooms extends Map<string, infer V> ? V : never {
  if (!rooms.has(roomId)) {
    const doc = new Y.Doc();
    rooms.set(roomId, { doc, connections: new Set(), awareness: new Map() });

    // Load persisted state
    redis.getBuffer(`room:${roomId}:state`).then(saved => {
      if (saved) Y.applyUpdate(doc, saved);
    });

    // Auto-save on updates
    doc.on('update', async (update: Uint8Array) => {
      const state = Y.encodeStateAsUpdate(doc);
      await redis.setBuffer(`room:${roomId}:state`, Buffer.from(state));
      await redis.expire(`room:${roomId}:state`, 86400 * 7);
    });
  }
  return rooms.get(roomId)!;
}

export function handleConnection(roomId: string, ws: WebSocket, userId: string, userName: string): void {
  const room = getOrCreateRoom(roomId);
  room.connections.add(ws);

  // Send current state
  const state = Y.encodeStateAsUpdate(room.doc);
  ws.send(JSON.stringify({ type: 'sync', data: Buffer.from(state).toString('base64') }));

  // Send current awareness
  for (const [id, awareness] of room.awareness) {
    ws.send(JSON.stringify({ type: 'awareness', userId: id, data: awareness }));
  }

  ws.addEventListener('message', (event) => {
    const msg = JSON.parse(event.data as string);

    switch (msg.type) {
      case 'update': {
        const update = Buffer.from(msg.data, 'base64');
        Y.applyUpdate(room.doc, update);
        // Broadcast to other connections
        for (const peer of room.connections) {
          if (peer !== ws && peer.readyState === 1) {
            peer.send(JSON.stringify({ type: 'update', data: msg.data }));
          }
        }
        break;
      }

      case 'awareness': {
        room.awareness.set(userId, msg.data);
        for (const peer of room.connections) {
          if (peer !== ws && peer.readyState === 1) {
            peer.send(JSON.stringify({ type: 'awareness', userId, data: msg.data }));
          }
        }
        break;
      }
    }
  });

  ws.addEventListener('close', () => {
    room.connections.delete(ws);
    room.awareness.delete(userId);
    // Notify others that user left
    for (const peer of room.connections) {
      if (peer.readyState === 1) {
        peer.send(JSON.stringify({ type: 'awareness_leave', userId }));
      }
    }
    // Clean up empty rooms after delay
    if (room.connections.size === 0) {
      setTimeout(() => {
        if (room.connections.size === 0) rooms.delete(roomId);
      }, 60000);
    }
  });
}

Step 3: Code Execution Sandbox

typescript
// src/editor/executor.ts
import { z } from 'zod';

const ExecutionRequest = z.object({
  code: z.string().max(50000),
  language: z.enum(['javascript', 'typescript', 'python', 'go', 'rust']),
  stdin: z.string().max(10000).default(''),
  timeoutSeconds: z.number().int().min(1).max(30).default(10),
});

const ExecutionResult = z.object({
  stdout: z.string(),
  stderr: z.string(),
  exitCode: z.number().int(),
  executionTimeMs: z.number(),
  memoryUsageMb: z.number().optional(),
});

export async function executeCode(
  request: z.infer<typeof ExecutionRequest>
): Promise<z.infer<typeof ExecutionResult>> {
  const { Sandbox } = await import('e2b');

  const sandbox = await Sandbox.create({
    template: getTemplate(request.language),
    timeoutMs: request.timeoutSeconds * 1000,
  });

  try {
    const filename = getFilename(request.language);
    await sandbox.filesystem.write(`/home/user/${filename}`, request.code);

    const cmd = getRunCommand(request.language, filename);
    const start = Date.now();

    const result = await sandbox.process.startAndWait({
      cmd,
      cwd: '/home/user',
      stdin: request.stdin,
      timeoutMs: request.timeoutSeconds * 1000,
    });

    return {
      stdout: result.stdout,
      stderr: result.stderr,
      exitCode: result.exitCode ?? 0,
      executionTimeMs: Date.now() - start,
    };
  } finally {
    await sandbox.close();
  }
}

function getTemplate(lang: string): string {
  const templates: Record<string, string> = {
    javascript: 'base', typescript: 'base', python: 'base', go: 'base', rust: 'base',
  };
  return templates[lang] ?? 'base';
}

function getFilename(lang: string): string {
  const filenames: Record<string, string> = {
    javascript: 'main.js', typescript: 'main.ts', python: 'main.py', go: 'main.go', rust: 'main.rs',
  };
  return filenames[lang] ?? 'main.js';
}

function getRunCommand(lang: string, filename: string): string {
  const commands: Record<string, string> = {
    javascript: `node ${filename}`,
    typescript: `npx tsx ${filename}`,
    python: `python3 ${filename}`,
    go: `go run ${filename}`,
    rust: `rustc ${filename} -o main && ./main`,
  };
  return commands[lang] ?? `node ${filename}`;
}

Step 4: Room API

typescript
// src/api/rooms.ts
import { Hono } from 'hono';
import { executeCode } from '../editor/executor';
import { Pool } from 'pg';

const app = new Hono();
const db = new Pool({ connectionString: process.env.DATABASE_URL });

app.post('/v1/rooms', async (c) => {
  const { language, template } = await c.req.json();
  const roomId = crypto.randomUUID().slice(0, 8);

  await db.query(`
    INSERT INTO rooms (id, language, created_by, created_at)
    VALUES ($1, $2, $3, NOW())
  `, [roomId, language, c.get('userId')]);

  return c.json({
    roomId,
    editorUrl: `https://editor.example.com/room/${roomId}`,
    wsUrl: `wss://editor.example.com/ws/${roomId}`,
  });
});

app.post('/v1/rooms/:roomId/execute', async (c) => {
  const { code, language, stdin } = await c.req.json();
  const result = await executeCode({ code, language, stdin, timeoutSeconds: 10 });
  return c.json(result);
});

export default app;

Results

  • Interview experience: both parties edit simultaneously, no more screen sharing
  • Cursor presence: see exactly where the other person is typing
  • Code execution: run code in 5 languages with 10-second timeout
  • Latency: <50ms sync between editors (CRDT + WebSocket)
  • Offline resilience: edits queue locally and sync when reconnected
  • Pair programming: 2-8 developers collaborate in same editor
  • Session persistence: code saved for 7 days, shareable via link

Related use cases