Express routes and static files
HTTP and WebSockets,without the ceremony.
Redweb is a small Node.js foundation for web apps, APIs, realtime features, multiplayer services, and server-rendered HTML. Start with one useful piece; compose them when the application grows.
Web on one side. Realtime on the other.
Express application
Static files and JSON APIs
WebSocket upgrades
Decorator-first rendered pages
One explicit shutdown path
Define your pages, sockets, and services together. Call app.run() when you’re ready to open the listener.
JSON and raw binary handlers
Server-rendered components
One explicit lifecycle
Build authenticated tic-tac-toe from the ground up.
Initialize once with Redweb, then add game rules, typed commands, connected players, server TSX, authentication, and one application entry point. Every chapter extends the same project.
Start the guided tutorial →What do you want to build?
Start with a working application. Understand the pieces, run the real tests, and know the deployment limits.
A clean starting point that stays understandable.
Redweb removes repetitive wiring while leaving pages, Express, Node servers, WebSocket routes, and handler classes visible and ordinary.
Express, already arranged
Serve static files, JSON APIs, and middleware without repeating the same server setup.
Messages find their handler
Give each socket path a route and each JSON message a type. Redweb owns upgrades, clients, binary frames, and lifecycle.
The server owns the state
Render TSX, inject application services, stream file actions, and project shared resources to connected pages.
Define once. Run together.
Register pages, socket routes, and application services with defineApp. One run() call owns startup and shutdown on a shared listener.
Readable TSX, from first render to realtime.
Write ordinary TypeScript and TSX. Decorators expose only the state and actions you choose. Redweb renders directly to HTML, scopes server actions, and uses one bounded socket when the page is live.
Open the realtime template walkthrough →This example is independent of the tic-tac-toe tutorial and includes its own setup and tests.
Complete setup, files and tests →
Browse application source, compiler configuration and assets
The generated build and test helpers come with redweb init.
import { action, defineApp, page, state } from 'redweb';
@page('/', { shared: true })
class CounterPage {
@state() count = 0;
@action()
increment() { this.count += 1; }
render() {
return <button rw-click="increment">Count {this.count}</button>;
}
}
const app = defineApp({ pages: [CounterPage] });
app.run();
Grow into stricter controls, route by route.
The simple path stays simple. When a game route needs more, opt into bounded rooms, sessions, admission, backpressure, protocol evolution, distribution, and draining.
Rooms
Bounded, route-local membership with deterministic disconnect cleanup.
Sessions
Application-issued resumable ownership with expiry and atomic takeover.
Fixed ticks
Drift-aware, non-overlapping simulation steps with bounded catch-up.
Protocol
Version negotiation, stable envelopes and codes, generated types, and codec hooks.
Distribution
A small broker seam with bounded fan-out and honest best-effort semantics.
Observability
Low-cardinality metrics for capacity, failures, readiness, rooms, and connections.
Define your app. Start HTTP and sockets together.
Define pages, socket routes and application services together. Nothing listens until run(); one owner starts and stops the shared HTTP/WebSocket listener.
A page at / and a socket route at /chat share one listener. This independent built-in template has its own setup, source files, and tests.
Open the HTTP + WebSocket template walkthrough →
Read the application API guide →Complete setup, files and tests →
Browse application source, compiler configuration and assets
The generated build and test helpers come with redweb init.
import { BaseHandler, defineApp, page, SocketRoute, type RedWebSocket } from 'redweb';
@page('/', { live: false })
class HomePage {
render() { return <h1>Hello from HTTP!</h1>; }
}
class Hello extends BaseHandler {
constructor() { super('hello'); }
onMessage(socket: RedWebSocket) {
socket.sendJson({ type: 'hello', message: 'Hello from WebSockets!' });
}
}
class ChatRoute extends SocketRoute {
constructor() { super({ path: '/chat', handlers: [Hello] }); }
}
const app = defineApp({ pages: [HomePage], sockets: [ChatRoute] });
await app.run();
A clear fit, with clear boundaries.
Choose Redweb for Node-hosted sites with live dashboards, chat, collaboration or routed socket endpoints. It is not React-compatible, an edge-only live runtime, or a managed identity, database or matchmaking service.
Use a maintained Node release for deployment; Node 18 is the core compatibility floor, not a production recommendation. Check runtime compatibility and release evidence →