Skip to main content


The socket primitive creates a Web Socket endpoint that can be connected to from your frontend.

Create a Socket

import { socket } from "@eventual/core";

export const mySocket = socket("mySocket", {
$connect: async ({ connectionId }) => {
// implement logic for when a client connects
$disconnect: async ({ connectionId }) => {
// implement logic for when a client disconnects
$default: async ({ connectionId }, { data }) => {
// handle message body

Connect from Frontend

You can connect to the web socket using the standard built-in WebSocket

const url = process.env.SERVICE_URL;

const ws = new WebSocket(url);

The SERVICE_URL can be retrieved for a deployed service using eventual get service:

eventual get service

# or if you have multiple:
eventual get service --service <your-service-name>

You should see a list of available endpoints like below. Copy the mySocket web socket endpoint in to your environment variables.

API Gateway:
Event Bus Arn: arn:aws:events:us-east-1:123456789019:event-bus/my-service
Service Log Group: my-service-execution-logs
Socket Endpoints:
mySocket - wss://

When developing locally, the eventual local command shows all of the available endpoints:

> eventual local
✔ Eventual Dev Server running on http://localhost:3111.
Sockets are available at:
rtc-socket - ws://localhost:3111/__ws/rtc-socket

Attach Middleware to a Socket

Middleware is helpful for sharing logic across API and Socket handlers.

Create a middleware chain socket.use. You can provide a function to be called as part of every connect, disconnect and default call.

// define a type for your message
interface MyMessage {
foo: string;
bar: string;

// create a middleware that parses the JSON message into a structured form
const myMiddleware = socket.use({
message: ({ request, context, next }) => {
const { body } = request;
const message = body
? (JSON.parse(body.toString()) as MyMessage)
: undefined;
return next({ ...context, message });

export const mySocket = myMiddleware.socket("mySocket", {
$connect: async ({ connectionId }, { message }) => {
// message is parsed now;;