> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deploybaseline.com/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSockets

> Which runtimes serve WebSocket endpoints and what the kit provides

Some APIs push to clients over a WebSocket instead of calling a webhook. Slack Socket Mode is the first one Baseline emulates: a Bolt app with `socketMode: true` connects to the emulator and receives events, button clicks, modal submissions, and slash commands over the socket. See [Slack Socket Mode](/slack.md#socket-mode) for the protocol details. The [Discord Gateway](/discord.md#gateway) is the second: discord.js, `@discordjs/ws`, and other Discord libraries connect to the URL `GET /api/v10/gateway/bot` returns, identify with intents, and receive guild, message, and interaction events, resuming after a disconnect.

## Install

Nothing to install. The Slack and Discord providers ship the WebSocket kit inside them, so `npx @deploybaseline/cli start` serves Socket Mode and the Gateway as it is. Each provider runs in its own process and owns its port, so a WebSocket connects straight to the provider, with nothing in between.

## Where it runs

| Runtime | WebSocket endpoints |
| - | - |
| CLI (`npx @deploybaseline/cli start`) | Yes. Stopping the CLI closes open connections with code 1001 |
| [`createEmulator`](/programmatic-api) | Yes. `close()` closes open connections with code 1001 |
| [Custom emulators](/custom-emulators.md) | Not yet. `app.upgrade` in a custom emulator fails at startup |

A handshake that reaches a handler which cannot upgrade the connection, such as a plain fetch call into the app, gets HTTP 501 with this body:

```json theme={null}
{
  "error": "WebSocket endpoints need a server that can upgrade connections. Run this service with the Baseline CLI or createEmulator; a plain fetch handler serves HTTP only.",
  "documentation_url": "https://docs.deploybaseline.com/websockets"
}
```

## The kit

Built-in providers serve WebSocket endpoints with core's `app.upgrade(path, handler)` and the helpers in `@deploybaseline/ws`:

* `webSocketRoute(app, path, { authorize, onConnection })` checks the handshake (return metadata, or an HTTP status such as 401 to refuse it), accepts it, tracks the connection, pings it, and closes it when the service stops.
* `ConnectionRegistry` lists open connections with message counts, broadcasts to a filtered set, reports changes, and closes everything with `closeAll()`.
* `startHeartbeat(socket, { intervalMs, maxMissed })` pings on an interval and drops a client that stops answering.
* `ResumeBuffer` keeps the last events of a session, numbered from 1, so a client that reconnects with the last number it saw can get what it missed.

`@deploybaseline/testing` has a client for tests that needs no extra dependency. It uses Node's built-in WebSocket:

```ts theme={null}
import { connectWs } from "@deploybaseline/testing";

const client = await connectWs("ws://localhost:4003/link/?ticket=...");
const hello = await client.next(); // the next message, JSON parsed
const event = await client.nextMatching((message) => message.type === "events_api");
client.send({ envelope_id: event.envelope_id });
await client.close();
```

WebSocket routes appear in coverage matrices as `WS /path`, next to HTTP routes, and the runtime coverage gate records a hit for each accepted handshake.

## Other transports

Baseline speaks HTTP, [GraphQL](/graphql.md), and WebSockets. gRPC is not supported, and no gRPC work is planned until a provider meets this bar: its official Node SDK has no REST fallback, and the vendor ships no official local emulator. Today no candidate does. Firestore's SDK accepts `preferRest: true`, and Google ships local emulators for Firestore and Pub/Sub.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.