Transform the current prototype into a fast, polished, production-ready collaborative code editor that outperforms OneCompiler in speed, UX, and real-time collaboration.
| Area | Current | Problem |
|---|---|---|
| Editor | CodeMirror 5 (CDN, legacy) | No native collab support, outdated API, missing features |
| Collaboration | Raw Socket.io setValue() on every keystroke |
Overwrites cursor position, race conditions, no conflict resolution, no remote cursors |
| Code Execution | JDoodle API (3rd-party, rate-limited) | Slow (~2-3s latency), only 3 languages, daily API limits, no stdin |
| Languages | Python, Java, C++ only | Missing JS, Go, Rust, C#, Ruby, PHP, TypeScript, etc. |
| UI/UX | Basic dark theme, no responsive layout | No keyboard shortcuts, no tab system, no themes, no file download |
| Architecture | Vanilla HTML + Express static serving | No bundler, no module system, CDN-dependent, hard to maintain |
Important
Compiler API Choice: I recommend using the Piston open-source code execution engine. It's free, self-hosted via Docker, supports 50+ languages, and has no rate limits. However, it requires you to run a Docker container alongside your Node.js server. If you prefer a hosted/no-Docker solution, we can use Judge0 Cloud API instead (free tier: 50 requests/day, paid tiers available). Which do you prefer?
Important
Architecture Decision: I plan to keep this as a vanilla HTML/CSS/JS frontend (no React/Vue) served by Express — this keeps it simple, fast to load, and easy to deploy. The major upgrade is switching from CDN-loaded CodeMirror 5 to a bundled CodeMirror 6 (via a simple Vite or esbuild build step for the frontend JS). This is necessary because CM6 is a proper ES module ecosystem. Are you okay with adding a lightweight build step (npm run build) for the frontend?
Important
- Deployment target: Where will you deploy this? (Render, Railway, VPS, AWS, etc.) This affects how we set up Piston.
- User accounts: Do you want user authentication (login/signup, save code history) in this version, or is the room-based anonymous model sufficient for now?
- STDIN support: Should users be able to provide input (stdin) before running? (e.g., for competitive programming problems) — I'm assuming yes.
The work is split into 5 phases, each producing a working, testable state.
This is the foundation. Everything else depends on having a modern editor.
- Minimal Vite config to bundle the frontend JS modules (CodeMirror 6 is ESM-only)
- Output to
public/dist/so Express can serve it as before
- CodeMirror 6 initialization with
@codemirror/view,@codemirror/state,basicSetup - Language mode registry mapping language keys → CM6 language packages
- Theme system:
oneDarkas default, with ability to switch - Keybindings: standard (
Ctrl+Sto save,Ctrl+Enterto run,Ctrl+/to toggle comment) - Line wrapping, bracket matching, auto-close brackets, indentation guides
- Search & replace panel (
Ctrl+F/Ctrl+H)
- Central language registry with metadata:
{ key: 'python', name: 'Python', mode: pythonLang, icon: '🐍', template: '# Start coding...\nprint("Hello, World!")' }
- 15+ languages with their CM6 syntax packages and boilerplate templates
- Add
devDependencies:vite,@codemirror/*packages, language packages - Add script:
"dev": "vite build --watch & node server/index.js","build": "vite build"
- Remove all CodeMirror 5 CDN
<link>and<script>tags - Replace with single
<script type="module" src="/dist/room.js"></script>
Languages to support with syntax highlighting (CM6 packages):
| Language | CM6 Package |
|---|---|
| Python | @codemirror/lang-python |
| JavaScript | @codemirror/lang-javascript |
| TypeScript | @codemirror/lang-javascript (TS mode) |
| Java | @codemirror/lang-java |
| C / C++ | @codemirror/lang-cpp |
| C# | @codemirror/lang-java (close enough) or @replit/codemirror-lang-csharp |
| Go | @codemirror/lang-go (community) |
| Rust | @codemirror/lang-rust |
| Ruby | codemirror-lang-ruby (community) |
| PHP | @codemirror/lang-php |
| HTML/CSS | @codemirror/lang-html, @codemirror/lang-css |
| SQL | @codemirror/lang-sql |
| Bash/Shell | codemirror-lang-bash (community) |
| Kotlin | Community package |
| Swift | Community package |
This is your killer feature. We replace the broken setValue() approach with proper CRDT-based sync.
- Initialize
Y.Docper room - Use
y-websocketprovider connecting to our Socket.io/WebSocket server - Bind
ytextto CodeMirror 6 viay-codemirror.next(yCollabextension) - Awareness protocol: show remote cursors with colored labels (user names/IDs)
- Y.UndoManager: per-user undo/redo that doesn't undo other people's changes
- Dedicated
y-websocketserver running alongside Express - Handles Yjs document sync, awareness broadcasting
- Room-based document isolation (each room = separate Y.Doc)
- Document persistence: save Y.Doc state to memory (upgrade to Redis/file later)
- Keep Socket.io for: comments, run-code events, user presence metadata
- Add
y-websocketserver on a sub-path (e.g.,/yjs) for document sync - Refactor room model: remove
codefield (Yjs owns the document state now) - Add language sync via Yjs shared map (
ymap.set('language', 'python'))
- ✅ Multiple users can edit simultaneously (not just author)
- ✅ No cursor jumping — each user's cursor stays in place
- ✅ Remote cursor visibility — see where others are typing
- ✅ Conflict-free — CRDT guarantees eventual consistency
- ✅ Offline resilience — edits queue and sync when reconnected
Replace JDoodle with a fast, unlimited, multi-language execution backend.
- Replace JDoodle API calls with Piston API calls
- Piston endpoint:
POST http://localhost:2000/api/v2/execute - Payload format:
{ "language": "python", "version": "3.10.0", "files": [{ "name": "main.py", "content": "print('hello')" }], "stdin": "optional input", "compile_timeout": 10000, "run_timeout": 5000, "compile_memory_limit": -1, "run_memory_limit": -1 } - Fetch available runtimes on startup (
GET /api/v2/runtimes) and cache them - Map our language keys to Piston language names + latest versions
- Return structured result:
{ stdout, stderr, exitCode, executionTime }
- Piston container setup:
services: piston: image: ghcr.io/engineer-man/piston ports: - "2000:2000" restart: unless-stopped
- Install language packages on first run via Piston's package manager API
- Accept stdin from the client before execution
- Pass it to Piston's
stdinfield - UI: textarea/input field below the editor for providing program input
Supported execution languages (via Piston):
Python, JavaScript (Node.js), TypeScript (Deno/ts-node), Java, C, C++, C#, Go, Rust, Ruby, PHP, Kotlin, Swift, Bash, Perl, Lua, R, Scala, Haskell, Dart, Elixir, and more.
Complete visual overhaul to make it look and feel like a $100/mo product.
- Design system: CSS custom properties for colors, spacing, radii, shadows
- Dark mode (default) with gorgeous gradients and glassmorphism
- Light mode toggle (for accessibility)
- Layout: Professional IDE layout with resizable panels
- Top: Toolbar (language picker, run button, share button, theme toggle, user avatars)
- Center: Code editor (full height, no wasted space)
- Bottom: Resizable output panel (drag handle to resize)
- Right (toggleable): Comment/chat sidebar
- Responsive: works on tablet; graceful mobile fallback
- Micro-animations: button hover effects, panel transitions, loading spinners
- Typography: Inter/JetBrains Mono (Google Fonts)
- Hero section with animated gradient background
- Room creation: auto-generate room IDs (UUID) with a "Copy Link" button
- Feature showcase cards with icons
- Professional footer
- SEO meta tags
- Professional toolbar with:
- Language dropdown (with icons/search)
- ▶ Run button (with
Ctrl+Enterhint) - Share button (copies room URL)
- Download button (saves code as file)
- Theme toggle (dark/light)
- Connected users avatars + count
- Execution status indicator (idle / running / error)
- Stdin input panel (collapsible, below toolbar)
- Output panel with:
- Tabs: "Output" | "Errors" (separated stdout/stderr)
- Execution time + memory display
- Copy output button
- Clear output button
- Status bar at bottom: language, cursor position (Ln/Col), encoding, connection status
| Feature | Shortcut | Description |
|---|---|---|
| Run Code | Ctrl+Enter |
Execute current code |
| Save/Download | Ctrl+S |
Download code as file |
| Toggle Comment | Ctrl+/ |
Comment/uncomment selection |
| Find & Replace | Ctrl+F / Ctrl+H |
Search panel |
| Increase Font | Ctrl+= |
Bigger editor font |
| Decrease Font | Ctrl+- |
Smaller editor font |
| Format Code | Shift+Alt+F |
Auto-indent (basic) |
| Full Screen | F11 |
Maximize editor |
- Rate limiting on code execution (per room, per IP)
- CORS configuration (restrict to your domain)
- Helmet.js for security headers
- Compression middleware (gzip)
- Graceful error handling and logging
- Room cleanup: auto-delete rooms after 24h inactivity
- Add
dist/,node_modules/,.env,piston-data/
- Professional README with setup instructions, screenshots, architecture diagram
- Page load: < 1.5s (bundled, gzipped assets)
- Code execution: < 1s for simple programs (Piston is local, no network hop)
- Collab sync latency: < 50ms (Yjs CRDT + WebSocket)
- First meaningful paint: < 800ms
┌─────────────────────────────────────────────────┐
│ Browser │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ Homepage │ │ Editor Room │ │
│ │ (index.html) │ │ CodeMirror 6 + Yjs CRDT │ │
│ │ │ │ + y-codemirror.next │ │
│ └──────────────┘ └────────┬─────────────────┘ │
└─────────────────────────────┼───────────────────┘
│
┌───────────────┼───────────────┐
│ WebSocket │ Socket.io │
│ (Yjs sync) │ (comments, │
│ │ run, presence)│
▼ ▼ │
┌─────────────────────────────────────────────────┐
│ Node.js + Express Server │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ y-websocket │ │ Socket.io Server │ │
│ │ (doc sync) │ │ (comments, execution) │ │
│ └──────────────┘ └────────┬─────────────────┘ │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ executor.js │ │
│ │ (Piston client) │ │
│ └─────────┬─────────┘ │
└──────────────────────────────┼───────────────────┘
│ HTTP
┌──────────▼──────────┐
│ Piston Engine │
│ (Docker container) │
│ 50+ languages │
└─────────────────────┘
# Build frontend (no errors)
npm run build
# Start server
npm start
# Verify Piston is running
curl http://localhost:2000/api/v2/runtimes | jq length
# Expected: 50+ runtimes
# Test code execution
curl -X POST http://localhost:2000/api/v2/execute \
-H "Content-Type: application/json" \
-d '{"language":"python","version":"3.10.0","files":[{"content":"print(42)"}]}'
# Expected: {"run":{"stdout":"42\n",...}}- Solo editing: Open a room, write code in 10+ languages, run each one, verify output
- Collaboration: Open the same room in 2+ browser tabs/windows:
- Type in both simultaneously — verify no cursor jumping, no data loss
- Verify remote cursors are visible with colored labels
- Verify language changes sync across all clients
- Verify output appears on all clients when code is run
- Stdin: Write a program that reads input, provide stdin, verify correct output
- UI: Verify all keyboard shortcuts work, theme toggle, responsive layout, download button
- Performance: Measure page load time, execution latency, collab sync latency
- Edge cases: Disconnect/reconnect, empty rooms, very long code, rapid typing