Serverless WebRTC signaling

Connect two browsers. Directly.

MeetPoint gets two browsers through the WebRTC handshake — then gets out of the way. A tiny typed SDK, one wss:// endpoint, and everything after the handshake flows peer-to-peer. No servers to run. No per-message fees. Your data never touches the middle.

Open a demo on two devices with the same room code. The match runs directly between them.

app.ts
import { SignalingClient } from 'meetpoint-client';

const signaling = new SignalingClient('wss://meetpoint.jimmycatgames.com');

signaling
  .on('connected',   () => signaling.joinLobby('room-42'))
  .on('peer_joined', ({ peerConnectionId, role }) => {
    // exchange offer/answer + ICE through the relay,
    // then talk directly over a WebRTC data channel
  })
  .on('peer_left',   () => console.log('peer disconnected'));

signaling.connect();

The server does one job, then disappears

WebRTC lets browsers talk directly — but they need a matchmaker to find each other first. That's all this is.

  1. 1

    Join a lobby

    Both peers open a WebSocket and join the same room code. The first one waits; the second triggers the pairing.

  2. 2

    Exchange the handshake

    Offer, answer and ICE candidates are relayed between the two peers. Relayed — not stored, not inspected.

  3. 3

    Go peer-to-peer

    The data channel opens and every byte after that flows directly between the browsers. The server sees nothing.

Don't take our word for it — open two tabs

Five zero-dependency demos, each a single HTML file, all running on this signaling service right now. Same room code on two devices and you're connected.

🏓
Neon Pong

Two-player Pong at 60 fps. Host-authoritative physics over a data channel.

Play →
💬
Neon Chat

1:1 messaging with typing indicators and presence — no chat server.

Open →
📦
Neon Drop

Send files browser-to-browser. Chunked binary transfer with backpressure.

Send →
🎨
Neon Board

Shared whiteboard with live remote cursors over an unreliable channel.

Draw →
📝
Neon Pad

Co-edit a document live. Keystrokes sync directly between peers.

Edit →
Your app here

Games, file transfer, collaborative tools, device pairing — anything that wants a direct line between two browsers.

Small surface, serious plumbing

🪶
Tiny typed SDK

One class, a handful of events, full TypeScript types. Auto-reconnect with exponential backoff built in. No framework required.

☁️
Serverless backend

API Gateway WebSocket + Lambda + DynamoDB. Nothing to patch, nothing idling — it scales to zero when nobody is connecting.

🔒
Private by design

The server only brokers the handshake. Offers, answers and ICE candidates are relayed, never stored — after that, traffic is peer-to-peer.

🚀
Deploy in minutes

One CDK deploy stands up the whole stack in your own AWS account, including a GitHub Actions OIDC pipeline. You own everything.

💸
Pay per handshake

Costs scale with connections made, not time connected. Hobby projects run for pennies; there is no per-message data fee.

🔌
Open protocol

Plain JSON over WebSocket — joinLobby, relaySignal, leaveLobby. Test it with wscat. No lock-in, no proprietary blob.

Kick the tires from a terminal

The protocol is plain JSON over WebSocket — you can drive it with wscat before writing a line of app code.

terminal
$ wscat -c "wss://meetpoint.jimmycatgames.com"
> {"action":"joinLobby","lobbyId":"room-42"}
< {"type":"waiting","lobbyId":"room-42"}

# second terminal, same lobby…
< {"type":"peer_joined","peerConnectionId":"…","role":"offerer"}

Or deploy the whole stack — API, examples site, CI pipeline — into your own AWS account:

terminal
$ git clone https://github.com/daveruiz/meetpoint-api.git
$ pnpm install
$ pnpm --filter meetpoint-infra deploy

MeetpointSignaling.WebSocketUrl = wss://xxxx.execute-api.…/prod