Express, already arranged
Serve static files, JSON APIs, middleware, and optional HTMX rendering without repeating the same server setup.
Redweb is a small Node.js foundation for serving web apps, APIs, and real-time features. Start an Express server, add typed WebSocket routes, or put both on one listener—without hiding the pieces you still want to control.
Use Redweb’s listener defaults, or supply your own server and keep control of when it starts and stops.
Redweb removes repetitive wiring while leaving Express, Node servers, WebSocket routes, and handler classes visible and ordinary.
Serve static files, JSON APIs, middleware, and optional HTMX rendering without repeating the same server setup.
Give each socket path a route and each JSON message a type. Redweb handles upgrades, clients, binary frames, and lifecycle.
Build the Express app without listening, attach WebSocket routes to the same Node server, then own one port and one shutdown path.
The simple path stays simple. When a game route needs more, opt into bounded rooms, sessions, admission, backpressure, protocol evolution, distribution, and draining without changing every other route.
Bounded, route-local membership with deterministic disconnect cleanup.
Application-issued resumable ownership with expiry and atomic takeover.
Drift-aware, non-overlapping simulation steps with bounded catch-up.
Version negotiation, stable envelopes and codes, generated types, and codec hooks.
A small broker seam with bounded fan-out and honest best-effort semantics.
Low-cardinality metrics for capacity, failures, readiness, rooms, and connections.
Build the Express side without binding, attach WebSocket routes to its Node server, then listen once. The detailed route, lifecycle, binary, and multiplayer APIs live in the reference.
Open the full API referenceconst { HttpServer, SocketServer } = require('redweb');
const http = new HttpServer({
port: 3030,
listen: false,
publicPaths: ['./public'],
services: [healthEndpoint],
});
new SocketServer({
server: http.server,
routes: [ChatRoute, PresenceRoute],
});
http.server.listen(3030);