Built for Macondo × Hack Club Where bros (and everyone else) code together in real time — no accounts, no servers, no nonsense.
┌──────────────────────────────────────────────────────────────────┐
│ { BroCode } JavaScript main.js ● Connected ✓ [Alice] [Bob] │
├────────────────┬─────────────────────────────────────────────────┤
│ CONNECTION │ ↩ Undo ↪ Redo ⇥ Indent // Comment A+ A− │
│ cs-BR0C0D3 ⎘ ├─────────────────────────────────────────────────┤
│ Name: Alice │ 1 // ✦ Welcome to BroCode 💯 │
│ Partner ID… │ 2 │
│ [Connect] │ 3 function greet(name) { │
│ [Disconnect] │ 4 return `What's good, ${name}!` ← Alice 🟢│
│ │ 5 } │
│ CHAT │ 6 │
│ Alice: Yo bro │ 7 const squad = ["Alice", "Bob"]; │
│ Bob: On it 👀 │ 8 squad.forEach(bro => { Bob 🔴 │
│ Alice: 😤 │ 9 console.log(greet(bro)); ▓▓▓▓▓▓▓▓ │
│ Bob: 💯 │ 10 }); │
│ [Type here…] │ 11 │
│ │ 12 // No server. No login. Just share an ID 🤝 │
│ ├─────────────────────────────────────────────────┤
│ │ JavaScript • 12 lines • Latency: 14ms │
└────────────────┴─────────────────────────────────────────────────┘
- Open in two browser tabs or two devices
- Copy your Peer ID → paste it into your partner's field → hit Connect
- Type anywhere — the other screen updates in real time
| Feature | What It Does |
|---|---|
| 🟢 Real-time code sync | Every keystroke broadcasts as a compact delta to your partner — no lag, no full-page snapshots |
| 🖱️ Dual live cursors | Your cursor is teal, your partner's is coral — both visible with floating name labels |
| 🔵 Remote selection highlight | See exactly what text your partner has selected |
| 💬 Built-in bro chat | Side-panel chat so you never have to switch tabs |
| 🌐 5 languages | JavaScript, Python, HTML, CSS, C++ with full syntax highlighting |
| 🔗 One-click ID share | Copy your 9-char Peer ID and send it via WhatsApp, Discord, anything |
| ↩️ Undo / Redo | Full per-user edit history |
| 💬 Comment toggle | Ctrl+/ or the toolbar button |
| 🔠 Font size controls | A+ / A− for any screen size |
| 📋 Copy code | Grab the whole editor content in one click |
| ⚡ Latency meter | Live ping/pong latency displayed in the status bar |
| 🔄 Auto-resync | If edits ever drift, a full snapshot resync fires automatically |
| 📡 Zero backend | 100% peer-to-peer WebRTC — the PeerJS relay only handles the initial handshake |
| Layer | Technology | Why |
|---|---|---|
| Networking | PeerJS v1.5.4 | WebRTC wrapper — direct P2P data channel |
| Signalling | 0.peerjs.com (free) |
Exchanges connection metadata; never sees your code |
| NAT traversal | Google STUN servers | Lets peers behind routers find each other |
| Editor | CodeMirror 5 | Professional in-browser editor with syntax highlighting |
| Fonts | JetBrains Mono + Space Grotesk | Mono for code, humanist sans for UI |
| Hosting | GitHub Pages | Free, instant, zero-config static hosting |
| Build tools | None | Single HTML file — no npm, no webpack, no Node.js |
You type a character
│
▼
CodeMirror fires 'change' event
→ {from: {line:3,ch:4}, to: {line:3,ch:4}, text: ["x"]}
│
▼
PeerJS DataConnection.send(delta)
│
WebRTC data channel — direct P2P, ~5–50ms latency
│
▼
Partner receives delta
│
▼
editor.replaceRange(text, from, to, '+remote')
(applying flag prevents echo loop)
│
▼
Cursor position broadcast follows immediately
| Type | Direction | Payload | Purpose |
|---|---|---|---|
delta |
both ↔ | {from, to, text} |
Incremental keystroke change |
full-sync |
either → | {code, lang} |
Full snapshot on connect or resync |
cursor |
both ↔ | {line, ch, label} |
Remote cursor position |
selection |
both ↔ | {anchor, head} |
Remote text selection highlight |
chat |
both ↔ | {text, name} |
Chat message |
meta |
both ↔ | {name} |
User display name announcement |
lang |
both ↔ | {lang} |
Language change sync |
ping / pong |
both ↔ | {ts} |
Round-trip latency measurement |
request-sync |
either → | — | Trigger a full resync after drift |
brocode/
├── index.html ← Entire application (HTML + CSS + JS in one file)
├── README.md ← This file
└── SETUP_GUIDE.md ← Step-by-step GitHub Pages deployment guide
The entire app lives in index.html. No dependencies to install, no build step, no config files.
# No installation needed — just open the file
open index.html # macOS
start index.html # Windows
xdg-open index.html # LinuxOpen a second browser tab with the same file and connect.
See SETUP_GUIDE.md for the full walkthrough, or:
# 1. Clone / create your repo
git clone https://github.com/YOUR_USERNAME/brocode.git
cd brocode
# 2. Push
git add index.html README.md SETUP_GUIDE.md
git commit -m "feat: BroCode real-time collaborative editor for Macondo"
git push origin main
# 3. Enable GitHub Pages
# Repo → Settings → Pages → Deploy from main → / (root) → Save
# 4. Your live URL:
# https://YOUR_USERNAME.github.io/brocode/- Open the URL in your browser
- Your Peer ID appears automatically (e.g.
cs-BR0C0D3) - Enter your Display Name in the sidebar
- Click 🔗 Share ID → copy it → send to your partner via Discord, WhatsApp, etc.
- Open the same URL
- Paste your partner's Peer ID into "Partner's Peer ID"
- Enter your Display Name
- Click Connect — green "Connected ✓" means you're live
- Type normally — every keystroke syncs to your partner instantly
- Your teal cursor and their coral cursor are both visible at all times
- Their selected text appears as a coral-tinted highlight on your screen
- Use the Chat panel to talk without switching apps
- Change the language from the dropdown — it syncs to your partner too
| Shortcut | Action |
|---|---|
Ctrl+/ or Cmd+/ |
Toggle line comment |
Tab |
Insert 2 spaces |
Ctrl+Z |
Undo |
Ctrl+Shift+I |
Copy your Peer ID to clipboard |
Escape |
Close the share modal |
Browser A Browser B
─────────────────────── ────────────────────────
CodeMirror Editor CodeMirror Editor
│ change events │ change events
▼ ▼
Delta encoder ──── WebRTC RTCDataChannel ────► Delta decoder
Delta decoder ◄──── direct P2P, no relay ────── Delta encoder
│ │
Remote cursor render Remote cursor render
Remote selection render Remote selection render
│ │
Chat panel ◄────── chat messages ──────► Chat panel
─────────────────────── ────────────────────────
↑
Signalling only
(0.peerjs.com)
Used ONCE during
connection setup —
never sees your code
| Browser | Support |
|---|---|
| Chrome / Edge 90+ | ✅ Full |
| Firefox 85+ | ✅ Full |
| Safari 15+ | ✅ Full |
| Opera 76+ | ✅ Full |
| Mobile Chrome / Safari | ✅ Full |
| Internet Explorer | ❌ WebRTC not supported |
| Problem | Solution |
|---|---|
peer-unavailable error |
Peer ID was mistyped — always use copy-paste |
| Can't connect on public/school WiFi | Some networks block WebRTC UDP. Switch to a mobile hotspot |
| Changes stopped syncing | Click Disconnect → reconnect. A full sync fires on every new connection |
| Partner's cursor not visible | Normal until they move — just type or click to trigger a broadcast |
peer-destroyed error |
Reload the page. A fresh Peer ID is generated on each load |
| GitHub Pages shows 404 | Confirm the file is named exactly index.html (lowercase) in the repo root |
Macondo is Hack Club's annual hackathon celebrating creative, technically interesting builds.
"It's Google Docs for code, but with zero backend. Share a 9-character ID with your bro — they paste it, click Connect, and you're both in the same editor in real time. Two cursors, built-in chat, any browser, one HTML file."
- Zero backend — BroCode is a static file. The PeerJS relay only touches the initial ICE handshake, never your code
- Delta sync — only
{from, to, text}diffs are transmitted (not full snapshots), making it fast even on 3G - Automatic resync — if deltas ever drift, a full snapshot fallback restores consistency immediately
- Real WebRTC — actual
RTCDataChannelwith ordered, reliable delivery; not a simulation or polling hack - Pixel-accurate cursors — CodeMirror bookmark widgets inject DOM nodes directly into the editor's text flow
MIT — free to use, fork, remix, and ship to hackathons.
| Dependency | License |
|---|---|
| PeerJS | MIT |
| CodeMirror 5 | MIT |
| JetBrains Mono | OFL-1.1 |
| Space Grotesk | OFL-1.1 |
{ BroCode } — because the best code is written with your crew. 🤝 Made with ❤️ for Macondo × Hack Club.