Wraps Express with sensible defaults (JSON body parsing, CORS, static asset folders) and starts listening immediately. You get the underlying Express instance back via `app`.
Options
- port: number (default 80)
- bind: string (default 0.0.0.0)
- publicPaths: string[] (default ["./public"])
- services: array of { serviceName, method, function }
- listenCallback: function invoked after listen
- encoding: "json" | "urlencoded" (default json)
- corsOptions: passed to cors
- enableHtmxRendering: boolean to render .htmx files
const { HttpServer, METHODS } = require('redweb')
const server = new HttpServer({
port: 4000,
bind: '0.0.0.0',
publicPaths: ['./static'],
services: [
{ serviceName: '/ping', method: METHODS.GET, function: (req, res) => res.json({ pong: true }) },
],
enableHtmxRendering: true,
})
// Express is still available:
server.app.get('/health', (req, res) => res.send('ok'))
Methods
constructor(options)
Merges defaults, wires body parsing, CORS, static serving, optional HTMX rendering, registers REST services, and starts listening.
app (Express instance)
Use the returned `app` to add middleware or routes exactly like a normal Express server.
TLS-enabled variant of `HttpServer`. Accepts `ssl.key` and `ssl.cert` file paths, wraps them in an https server, and bootstraps the same middleware pipeline.
Options
- All `HttpServer` options
- ssl.key: path to private key (required)
- ssl.cert: path to certificate (required)
const { HttpsServer, METHODS } = require('redweb')
new HttpsServer({
port: 4443,
ssl: { key: './certs/dev.key', cert: './certs/dev.crt' },
services: [
{ serviceName: '/secure', method: METHODS.GET, function: (req, res) => res.json({ ok: true }) },
],
})
Methods
constructor(options)
Loads the provided key/cert pair, builds the Express app with BaseHttpServer, then creates and starts the HTTPS listener.
HTTP-upgrade WebSocket server on top of `ws`. Builds its own HTTP server unless you pass one in, wires one or more `SocketRoute` instances, and exposes helpers for runtime route changes.
Options
- port: number (default 3000)
- server: existing http.Server to attach to (optional)
- routes: array of SocketRoute subclasses (defaults to a single DefaultRoute at "/")
const { SocketServer } = require('redweb')
const { ChatRoute } = require('./routes/ChatRoute')
const sockets = new SocketServer({
port: 3000,
routes: [ChatRoute],
})
Methods
constructor(options)
Creates (or reuses) an HTTP server, instantiates supplied routes (or a DefaultRoute), attaches upgrade handling, and starts listening.
addRoute(RouteClass)
Instantiate and register another `SocketRoute` at runtime.
handleUpgrade(req, socket, head)
Internal: normalises the request path, picks a matching route (or "/"), and forwards the upgrade to that route's server.
shutdown()
Closes all registered routes and the underlying HTTP server.
HTTPS + WebSocket pairing. Mirrors `SocketServer` but wraps an HTTPS server built from the provided TLS files.
Options
- port: number (default 3000)
- ssl.key and ssl.cert: required file paths
- routes: array of SocketRoute subclasses
const { SecureSocketServer } = require('redweb')
const { GameRoute } = require('./routes/GameRoute')
new SecureSocketServer({
port: 3443,
ssl: { key: './certs/dev.key', cert: './certs/dev.crt' },
routes: [GameRoute],
})
Methods
constructor(options)
Loads TLS files, builds an HTTPS server, registers the provided routes, attaches upgrade handling, and starts listening.
addRoute(RouteClass)
Same runtime route attachment as `SocketServer`.
shutdown()
Stops routes, services, and the HTTPS listener.
Defines a WebSocket endpoint, maps client messages to handlers, and manages per-route services. Routes are constructed with handler classes, not instances.
Options
- path: WebSocket path (required)
- handlers: array of handler classes (required)
- services: array of SocketService subclasses (optional)
- allowDuplicateConnections: allow multiple clients from the same IP
const { SocketRoute } = require('redweb')
const { ChatHandler } = require('./handlers/ChatHandler')
const { ClockService } = require('./services/ClockService')
class ChatRoute extends SocketRoute {
constructor() {
super({
path: '/chat',
handlers: [ChatHandler],
services: [ClockService],
allowDuplicateConnections: true,
})
}
}
Methods
constructor({ path, handlers, services, allowDuplicateConnections })
Validates input, instantiates handlers/services, sets up a `ws` server for the path, and registers connection listeners.
addHandler(HandlerClass)
Adds another handler class unless a handler with the same name already exists.
handleConnection(socket, req)
Stores the client (deduping by IP unless allowed), decorates the socket with `sendJson`/`broadcast`, and wires close/error/message listeners.
handleMessage(socket, data)
Finds the handler matching `data.type`; on success delegates to handler.handleMessage, otherwise replies with an error and closes the socket.
handleClose(socket, ip)
Removes the client from the registry and triggers an optional `connectionCloseCallback`.
shutdown()
Stops services (calls onShutdown on each) and closes the route's WebSocket server.
handleError(socket, error, ip)
Logs socket errors; override for custom reporting.
Route-scoped background worker. Used by `SocketRoute` to run ticks or lifecycle hooks tied to a specific route.
const { SocketService } = require('redweb')
class ClockService extends SocketService {
constructor() { super('clock', 1000) }
onTick() {
this.route.clients.forEach((socket) => socket.sendJson({ type: 'time', now: Date.now() }))
}
}
Methods
constructor(name, tickRateMs = null)
Stores a service id and optional tick interval; the interval is activated in onInit if onTick exists.
onInit(route)
Called once by SocketRoute, sets `this.route` and, if a tick interval was supplied, schedules recurring onTick execution.
onTick()
Optional; implement to run on the configured interval.
onShutdown()
Clears the tick interval; extend for cleanup hooks.
Small EventEmitter-backed list for socket-scoped entities (players, rooms, etc.). Emits `added` and `removed` events.
const { SocketRegistry } = require('redweb')
class PlayerRegistry extends SocketRegistry {
addPlayer(player) {
this.add(player)
this.emit('playerJoined', player)
}
}
Methods
add(item)
Stores the item and emits an `added` event.
remove(itemOrId, by = "id")
Remove by object reference or by matching a property (defaults to "id"); returns true when removal occurred and emits `removed`.
all()
Returns a shallow copy of all stored items.
count()
Convenience getter for `all().length`.
Abstract message handler. Provide a name in the constructor; clients send `{ type: name, ... }` to target it.
const { BaseHandler } = require('redweb')
class ChatHandler extends BaseHandler {
constructor() { super('chat') }
onMessage(socket, message) {
socket.broadcast({ type: 'chat', text: message.text })
}
}
Methods
constructor(name)
Stores the handler name used by incoming messages.
handleMessage(socket, message)
Calls onMessage; override only if you need pre/post handling logic.
onMessage(socket, message)
Required; implement your message processing here. Throwing will close the socket with an error.
onInitialContact(socket)
Optional hook for first-touch logic (not used by default route).
Utility to JSON.stringify data and send it over a `ws` socket.
Methods
sendJson(socket, data)
Serialises data and writes it to the socket.
Default WebSocket server options used by BaseSocketServer.
const { SOCKET_OPTIONS } = require('redweb')
// { port: 3000, ssl: null, routes: [] }
Methods
port
Default WebSocket port (3000).
ssl
Default TLS config (null).
routes
Routes array default (empty; a DefaultRoute is created when none are provided).
Lowercase HTTP verb helpers passed straight to Express route registration.
Methods
GET
Use with services array or Express: METHODS.GET
POST
Use with services array or Express: METHODS.POST
PUT
Use with services array or Express: METHODS.PUT
DELETE
Use with services array or Express: METHODS.DELETE