REDWEB
Reference guide
HTTP

HttpServer

Back to top

Wraps Express with sensible defaults (JSON body parsing, CORS, static asset folders) and starts listening immediately unless `listen: false` is supplied. 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 }
  • listen: boolean (default true); set false to build app without binding a port
  • listenCallback: function invoked after listen
  • encoding: "json" | "urlencoded" (default json)
  • corsOptions: passed to cors
  • enableHtmxRendering: boolean to render .htmx files
js
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 unless listen is false.

app (Express instance)

Use the returned `app` to add middleware or routes exactly like a normal Express server.

HTTP

BaseHttpServer

Back to top

Public Express app builder used by HttpServer and HttpsServer. Use it for advanced composition when you want Redweb middleware, static files, services, and HTMX rendering without any listener behavior.

Options
  • All `HttpServer` app-building options
  • server: existing Express application to configure
  • listen is ignored because BaseHttpServer never binds a port
js
const { BaseHttpServer, METHODS } = require('redweb')

const base = new BaseHttpServer({
  publicPaths: ['./public'],
  services: [
    { serviceName: '/health', method: METHODS.GET, function: (req, res) => res.json({ ok: true }) },
  ],
})

base.app.get('/extra', (req, res) => res.send('ok'))
Methods
constructor(options)

Builds or configures an Express app with body parsing, CORS, static serving, optional HTMX rendering, and REST services.

app (Express instance)

The configured Express application. Pass it to http.createServer(app) for custom server ownership.

HTTP

HttpsServer

Back to top

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)
js
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 unless listen is false.

WebSocket

SocketServer

Back to top

HTTP-upgrade WebSocket server on top of `ws`. Builds and listens on its own HTTP server by default; if you pass a Node `server`, it attaches upgrade handling and leaves `.listen()` to you unless `listen: true` is explicit.

Options
  • port: number (default 3000)
  • listen: boolean (default true for owned servers); supplied servers do not listen unless explicitly true
  • server: existing http.Server to attach to without double-listening (optional)
  • routes: array of SocketRoute subclasses (defaults to a single DefaultRoute at "/")
js
const http = require('http')
const { HttpServer, METHODS, SocketServer } = require('redweb')

const httpServer = new HttpServer({
  listen: false,
  publicPaths: ['./public'],
  services: [
    { serviceName: '/health', method: METHODS.GET, function: (req, res) => res.json({ ok: true }) },
  ],
})

const server = http.createServer(httpServer.app)

new SocketServer({
  server,
  routes: [ChatRoute],
})

server.listen(3030)
Methods
constructor(options)

Creates or reuses an HTTP server, instantiates supplied routes or a DefaultRoute, attaches upgrade handling, and starts listening only when Redweb owns the server or listen is explicitly true.

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.

WebSocket

SecureSocketServer

Back to top

HTTPS + WebSocket pairing. Mirrors `SocketServer` but wraps an HTTPS server built from the provided TLS files.

Options
  • port: number (default 3000)
  • listen: boolean (default true for owned servers); supplied servers do not listen unless explicitly true
  • server: existing https.Server to attach to without double-listening (optional)
  • ssl.key and ssl.cert: required file paths
  • routes: array of SocketRoute subclasses
js
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 or reuses a supplied HTTPS server, registers the provided routes, attaches upgrade handling, and starts listening only when Redweb owns the server or listen is explicitly true.

addRoute(RouteClass)

Same runtime route attachment as `SocketServer`.

shutdown()

Stops routes, services, and the HTTPS listener.

WebSocket

SocketRoute

Back to top

Defines a WebSocket endpoint, maps JSON text messages to handlers, dispatches binary frames to binary-capable 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
  • websocketOptions: options passed to ws WebSocketServer, such as maxPayload or perMessageDeflate
js
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,
      websocketOptions: {
        maxPayload: 1024 * 1024,
        perMessageDeflate: false,
      },
    })
  }
}
Methods
constructor({ path, handlers, services, allowDuplicateConnections, websocketOptions })

Validates input, instantiates handlers/services, sets up a `ws` server for the path with any websocketOptions, 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)

Parses JSON text frames, finds the handler matching `data.type`; on success delegates to handler.handleMessage, otherwise replies with an error and closes the socket.

handleBinaryMessage(socket, buffer)

Handles binary frames separately from JSON text frames and delegates to a handler selected by acceptsBinary(socket, buffer).

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.

WebSocket

SocketService

Back to top

Route-scoped background worker. Used by `SocketRoute` to run ticks or lifecycle hooks tied to a specific route.

js
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.

WebSocket

SocketRegistry

Back to top

Small EventEmitter-backed list for socket-scoped entities (players, rooms, etc.). Emits `added` and `removed` events.

js
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`.

WebSocket

BaseHandler

Back to top

Abstract message handler. Provide a name in the constructor; clients send `{ type: name, ... }` to target JSON messages, while binary frames can be accepted and handled as raw Buffer payloads.

js
const { BaseHandler } = require('redweb')

class UploadHandler extends BaseHandler {
  constructor() { super('upload') }

  onMessage(socket, message) {
    socket.sendJson({ type: 'upload:control', action: message.action })
  }

  acceptsBinary(socket, buffer) {
    return buffer.length > 0
  }

  onBinaryMessage(socket, buffer) {
    socket.sendJson({ type: 'upload:chunk', bytes: buffer.length })
  }
}
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.

acceptsBinary(socket, buffer)

Optional selector used by SocketRoute to choose a handler for binary frames. Return true when this handler should receive the Buffer.

handleBinaryMessage(socket, buffer)

Calls onBinaryMessage. If onBinaryMessage is not implemented, Redweb sends a "Binary messages are not supported by this handler" error.

onBinaryMessage(socket, buffer)

Optional; override for normal binary-message handling. The second argument is the raw Buffer payload.

onInitialContact(socket)

Optional hook for first-touch logic (not used by default route).

Utility

sendJson

Back to top

Utility to JSON.stringify data and send it over a `ws` socket.

js
const { sendJson } = require('redweb')

sendJson(socket, { type: 'ping' })
Methods
sendJson(socket, data)

Serialises data and writes it to the socket.

Constants

SOCKET_OPTIONS

Back to top

Default WebSocket server options used by BaseSocketServer.

js
const { SOCKET_OPTIONS } = require('redweb')
// { port: 3000, ssl: null, listen: true, routes: [] }
Methods
port

Default WebSocket port (3000).

ssl

Default TLS config (null).

listen

Owned socket servers listen by default. Supplied servers remain caller-owned unless listen is explicitly true.

routes

Routes array default (empty; a DefaultRoute is created when none are provided).

Constants

METHODS

Back to top

Lowercase HTTP verb helpers passed straight to Express route registration.

js
const { METHODS } = require('redweb')
// METHODS.GET, METHODS.POST, METHODS.PUT, METHODS.DELETE
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