Hono
Mount the pipedog WebRTC offer and WebSocket endpoints in a Hono app on Bun.
Hono routes the offer, and upgrades /ws with its own WebSocket helper and pipedog's Hono adapter,
honoWebsocket. This snippet runs on Bun.
Install
bun add @pipedog/core @pipedog/asyncio @pipedog/transport-smallwebrtc @pipedog/transport-websocket @pipedog/serializer-protobuf @pipedog/openai @pipedog/audio-silero @pipedog/audio-smart-turn hono@pipedog/audio-smart-turn isn't imported anywhere: the default turn strategies load it. To run
the snippet from a checkout instead, see Installation.
Files
The endpoints come from the shared module on the overview.
voice.ts re-exports it:
export { offer, runSocketAgent, socket } from "../shared/voice.ts";
import { honoWebsocket } from "@pipedog/transport-websocket/hono";
import { Hono } from "hono";
import { upgradeWebSocket, websocket } from "hono/bun";
import { offer, runSocketAgent } from "./voice.ts";
const app = new Hono();
app.post("/api/offer", (c) => offer(c.req.raw));
app.get(
"/ws",
upgradeWebSocket(() => honoWebsocket(runSocketAgent)),
);
// Bun serves the app; on Node, use @hono/node-server with the same routes.
export default { fetch: app.fetch, websocket };
Run it
OPENAI_API_KEY=sk-... bun app.tsBun serves the default export on port 3000, or on $PORT. The offer is at POST /api/offer and the
WebSocket at /ws.
Other runtimes
- Node. Serve the app with
@hono/node-server, with the same routes.hono/bun'supgradeWebSocketis Bun only, so use Hono's Node WebSocket helper (@hono/node-ws) withhonoWebsocketfor/ws, or servesocketon its own withserveFetch(socket, { port })from@pipedog/transport-websocket/serve, which upgrades on Node with thewspackage. - Cloudflare Workers.
socketis a fetch handler that Workers can upgrade, so mount it directly, without the Bun helper:app.get("/ws", (c) => socket(c.req.raw)). Leave the offer, and the WebRTC transport, out of a Workers build: Workers have no UDP. A session that should outlive one request belongs in a Durable Object; see Cloudflare Workers.
Deploy
Run it as a long-lived Bun process. The offer's media runs over UDP, so a serverless host can't carry it.
Authentication
Neither route has auth. Wrap offer and the socket route with a session check before they run, as
in Authentication. Hono middleware on both routes works too.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).