Web APIs Cheatsheet
WebSocket API
Use this Web APIs reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Creating a Connection
const ws = new WebSocket('wss://api.example.com/socket'); // With sub-protocols (server selects one) const ws = new WebSocket('wss://api.example.com/socket', ['json', 'binary']); ws.protocol; // sub-protocol server selected (string) ws.url; // connection URL ws.binaryType; // 'blob' (default) | 'arraybuffer' ws.bufferedAmount; // bytes queued but not yet sent ws.extensions; // negotiated extensions string
readyState Values
| Value | Constant | Meaning |
|---|---|---|
0 | WebSocket.CONNECTING | Connection not yet open |
1 | WebSocket.OPEN | Open and ready to send |
2 | WebSocket.CLOSING | Closing handshake in progress |
3 | WebSocket.CLOSED | Connection closed |
ws.readyState === WebSocket.OPEN; // safe to sendEvent Handlers
ws.addEventListener('open', e => { console.log('Connected'); ws.send('hello'); }); ws.addEventListener('message', e => { // e.data is string | Blob | ArrayBuffer depending on binaryType if (typeof e.data === 'string') { const msg = JSON.parse(e.data); } else if (e.data instanceof ArrayBuffer) { const view = new Uint8Array(e.data); } }); ws.addEventListener('close', e => { e.code; // close code (1000 = normal, 1006 = abnormal) e.reason; // string reason e.wasClean; // boolean }); ws.addEventListener('error', e => { // e is a generic Event — no detail; check network tab console.error('WebSocket error', e); });
Common Close Codes
| Code | Meaning |
|---|---|
1000 | Normal closure |
1001 | Endpoint going away (page unload, server restart) |
1002 | Protocol error |
1003 | Unsupported data type |
1006 | Abnormal closure (connection lost, no close frame) |
1007 | Invalid frame payload |
1008 | Policy violation |
1009 | Message too large |
1011 | Unexpected server error |
4000–4999 | Application-defined codes |
Sending Data
// String ws.send('plain text'); ws.send(JSON.stringify({ type: 'ping' })); // Binary ws.send(new ArrayBuffer(8)); ws.send(new Uint8Array([1, 2, 3])); ws.send(new Blob(['binary data'])); // Guard: only send when open if (ws.readyState === WebSocket.OPEN) ws.send(data);
Closing the Connection
ws.close(); // normal close, code 1000 ws.close(1000, 'Done'); // code + reason (≤123 bytes UTF-8) ws.close(4001, 'Auth failed');
Receiving Binary Data
ws.binaryType = 'arraybuffer'; // change before or after open ws.addEventListener('message', e => { const buf = e.data; // ArrayBuffer const view = new DataView(buf); view.getUint8(0); new Uint8Array(buf); }); // blob (default) — convert when needed ws.binaryType = 'blob'; ws.addEventListener('message', async e => { const buf = await e.data.arrayBuffer(); });
Reconnection Pattern
function createSocket(url, onMessage) { let ws, reconnectTimer; function connect() { ws = new WebSocket(url); ws.addEventListener('open', () => { console.log('WebSocket open'); clearTimeout(reconnectTimer); }); ws.addEventListener('message', e => onMessage(JSON.parse(e.data))); ws.addEventListener('close', e => { if (!e.wasClean) { reconnectTimer = setTimeout(connect, 2000); // retry after 2 s } }); ws.addEventListener('error', () => ws.close()); } connect(); return { send: data => ws.readyState === WebSocket.OPEN && ws.send(JSON.stringify(data)), close: () => { clearTimeout(reconnectTimer); ws.close(1000); }, }; }
Heartbeat / Ping-Pong
The browser WebSocket API doesn't expose ping frames directly. Implement an application-level heartbeat.
let heartbeat; ws.addEventListener('open', () => { heartbeat = setInterval(() => { if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'ping' })); }, 30000); }); ws.addEventListener('message', e => { const msg = JSON.parse(e.data); if (msg.type === 'pong') return; // ignore heartbeat responses handleMessage(msg); }); ws.addEventListener('close', () => clearInterval(heartbeat));
Backpressure / bufferedAmount
// Don't flood the socket — wait until buffer drains function sendThrottled(ws, data) { if (ws.bufferedAmount > 64 * 1024) { // 64 kB threshold setTimeout(() => sendThrottled(ws, data), 50); return; } ws.send(data); }
Authentication Patterns
The browser WebSocket handshake cannot set custom headers. Use one of these approaches:
// 1. Token in URL query parameter (visible in logs — use short-lived tokens) const ws = new WebSocket(`wss://api.example.com/ws?token=${token}`); // 2. Send auth message immediately after open ws.addEventListener('open', () => { ws.send(JSON.stringify({ type: 'auth', token })); }); // 3. Cookie-based — cookies are sent automatically on same-origin WS const ws = new WebSocket('wss://same-origin.example.com/ws');
WebSocket in a Worker
// WebSocket works in dedicated and shared workers // worker.js const ws = new WebSocket('wss://api.example.com/ws'); ws.onmessage = e => postMessage(e.data); onmessage = e => ws.send(e.data);
Common Message Protocol Patterns
// Typed message envelope const send = (ws, type, payload) => ws.send(JSON.stringify({ type, payload, ts: Date.now() })); ws.addEventListener('message', e => { const { type, payload } = JSON.parse(e.data); handlers[type]?.(payload); }); // Request-response over WebSocket const pending = new Map(); function request(ws, type, payload) { const id = crypto.randomUUID(); return new Promise((resolve, reject) => { pending.set(id, { resolve, reject }); ws.send(JSON.stringify({ id, type, payload })); setTimeout(() => { pending.delete(id); reject(new Error('Timeout')); }, 10000); }); } ws.addEventListener('message', e => { const { id, result, error } = JSON.parse(e.data); if (!pending.has(id)) return; const { resolve, reject } = pending.get(id); pending.delete(id); error ? reject(new Error(error)) : resolve(result); });
Difference vs SSE vs Long Polling
| Feature | WebSocket | Server-Sent Events | Long Polling |
|---|---|---|---|
| Direction | Full-duplex | Server → client | Server → client |
| Protocol | WS / WSS | HTTP | HTTP |
| Reconnect | Manual | Automatic | Manual |
| Binary support | Yes | No (text only) | With encoding |
| Proxies | May block WS | Works everywhere | Works everywhere |
| Browser support | All | All modern | All |