Socket.IO -- Setup & Configuration
Real-time, bidirectional, event-based communication using Socket.IO -- with automatic runtime detection for Node.js and Bun, horizontal scaling via Redis, and a built-in authentication handshake.
Quick Reference
| Item | Value |
|---|---|
| Package | @venizia/ignis (core) |
| Class | SocketIOComponent |
| Server Helper | SocketIOServerHelper |
| Client Helper | SocketIOClientHelper |
| Runtimes | Node.js (@hono/node-server) and Bun (native) |
| Scaling | @socket.io/redis-adapter + @socket.io/redis-emitter |
IMPORTANT
SocketIOComponent and SocketIOBindingKeys are not exported from the @venizia/ignis barrel -- import from the @venizia/ignis/socket-io subpath.
// From core -- subpath import (NOT from '@venizia/ignis')
import { SocketIOComponent, SocketIOBindingKeys } from '@venizia/ignis/socket-io';
// From helpers -- subpath import
import { SocketIOServerHelper, SocketIOClientHelper, SocketIOConstants } from '@venizia/ignis-helpers/socket-io';
import type { TSocketIOAuthenticateFn, TSocketIOValidateRoomFn } from '@venizia/ignis-helpers/socket-io';Use cases:
- Live notifications and alerts
- Real-time chat and collaborative editing
- Live dashboards and monitoring streams
- Multiplayer game state synchronization
- Service-to-service real-time messaging (via
SocketIOClientHelper)
Setup
Three pieces are bound in preConfigure(), before the component itself is registered:
| Step | Binding key | Required |
|---|---|---|
| 1. Redis connection | SocketIOBindingKeys.REDIS_CONNECTION | Yes |
| 2. Authenticate handler | SocketIOBindingKeys.AUTHENTICATE_HANDLER | Yes |
| 3. Room / connected handlers | VALIDATE_ROOM_HANDLER, CLIENT_CONNECTED_HANDLER | No |
import { BaseApplication } from '@venizia/ignis';
import { SocketIOComponent, SocketIOBindingKeys } from '@venizia/ignis/socket-io';
import { RedisSingleHelper, ValueOrPromise } from '@venizia/ignis-helpers';
import type { TSocketIOAuthenticateFn } from '@venizia/ignis-helpers/socket-io';
export class Application extends BaseApplication {
preConfigure(): ValueOrPromise<void> {
// 1. Redis connection -- required for the adapter + emitter
const redisHelper = new RedisSingleHelper({
name: 'socket-io-redis',
host: process.env.REDIS_HOST ?? 'localhost',
port: +(process.env.REDIS_PORT ?? 6379),
autoConnect: false,
});
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION }).toValue(redisHelper);
// 2. Authentication handler -- required
const authenticateFn: TSocketIOAuthenticateFn = handshake => !!handshake.headers.authorization;
this.bind({ key: SocketIOBindingKeys.AUTHENTICATE_HANDLER }).toValue(authenticateFn);
// 3. Register the component
this.component(SocketIOComponent);
}
}WARNING
autoConnect: false is required on the Redis helper -- the server helper duplicates the connection into 3 independent clients and connects them itself during configure(). Connecting the parent first races against the duplicates. Full step-by-step setup (Bun peer dependency, room validation, cluster/sentinel Redis, the autoConnect rationale) is in Usage & Examples.
How It Works
- Post-start hook, not immediate init. Socket.IO needs a running server, but components initialize before the server starts.
binding()resolves all bindings and registers a post-start hook; the hook buildsSocketIOServerHelperand binds it toSOCKET_IO_INSTANCEonly afterstart()brings the server up. - Runtime detection picks the wiring.
RuntimeModules.detect()selects Node.js (Socket.IO attaches tonode:http.Serverdirectly) or Bun (@socket.io/bun-engineis dynamically imported and wired intoserver.reload()). See the runtime matrix for the full comparison. - One Redis connection becomes three. The connection you bind is never consumed directly -- the helper calls
duplicateClient()three times: a pub/sub pair for the Redis adapter (cross-instance room broadcast) and a third client for the Redis emitter (cross-instance direct send). - Authentication is mandatory. Every client starts
unauthorizedand must emitauthenticatewithinauthenticateTimeout(default 10s) or it is disconnected. Success joins the client to the default rooms and starts a keep-alive ping. - Room joins are opt-in by default. Without a bound
VALIDATE_ROOM_HANDLER, everyjoinrequest is silently rejected -- security-by-default, not a bug.
Common Tasks
Restrict CORS for production. Bind SERVER_OPTIONS before registering the component -- the default (cors.origin: '*') is for local development only.
import type { ServerOptions } from 'socket.io';
this.bind<Partial<ServerOptions>>({ key: SocketIOBindingKeys.SERVER_OPTIONS }).toValue({
cors: { origin: ['https://myapp.com'], credentials: true },
});
this.component(SocketIOComponent);Send a message from a service. SOCKET_IO_INSTANCE is bound by the component after the server starts, so resolve it lazily -- never @inject it in a constructor. Full pattern in Usage & Examples.
this.io.send({ destination: userId, payload: { topic: 'notification', data } });Scale Redis beyond a single node. Swap RedisSingleHelper for RedisClusterHelper or RedisSentinelHelper -- both satisfy the IRedisHelper interface the component validates against. See Redis Connection Alternatives.
Look up every default, binding key, and constant. Full DEFAULT_SERVER_OPTIONS, the binding key table, system events, default rooms, and the client state machine are in the API Reference.
See Also
- Usage & Examples -- Full setup steps, server-side usage, client helper, advanced patterns
- API Reference -- Architecture, configuration reference, method signatures, internals, types
- Error Reference -- Error conditions and troubleshooting
- Guides:
- Components Overview -- Component system basics
- Application -- Registering components
- Components:
- Components Index -- All built-in components
- Helpers:
- Socket.IO Helper -- Full
SocketIOServerHelper+SocketIOClientHelperAPI reference
- Socket.IO Helper -- Full
- External Resources:
- Socket.IO Documentation -- Official docs
- Socket.IO Redis Adapter -- Horizontal scaling guide
- @socket.io/bun-engine -- Bun runtime support
- Tutorials:
- Real-Time Chat -- Building a chat app with Socket.IO
- Changelog:
- 2026-02-06: Socket.IO Integration Fix -- Lifecycle timing fix + Bun runtime support
Files:
packages/core/src/components/socket-io/component.ts--SocketIOComponentpackages/core/src/components/socket-io/common/keys.ts--SocketIOBindingKeyspackages/core/src/components/socket-io/common/types.ts--IServerOptions,DEFAULT_SERVER_OPTIONS