---
title: "Deploy WebSocket | Node Server Sharing One Port with HTTP"
description: "WebSocket server on Node and TypeScript, HTTP health check on the same port"
category: "Starters"
url: https://railway.com/deploy/websocket-or-node-server-sharing-one-por
---

# Deploy WebSocket | Node Server Sharing One Port with HTTP

WebSocket server on Node and TypeScript, HTTP health check on the same port

**[Deploy WebSocket | Node Server Sharing One Port with HTTP on Railway](https://railway.com/template/websocket-or-node-server-sharing-one-por)**

- **Creator:** Pavel Volkov's Projects
- **Category:** Starters
- **Total deploys:** 2

## Template content

### WebSocket

- **Source:** https://github.com/ak40u/websocket-railway-starter
- **Public domain:** Yes

## Documentation

# Deploy and Host a WebSocket Server on Railway

A WebSocket server on Node 24 and TypeScript, sharing one port with an HTTP endpoint - which is what makes it deployable.

## About Hosting WebSockets

The Node.js WebSocket template on Railway builds from a repository last updated in September 2024, with esbuild 0.17 and a pnpm bundling pipeline. Under four deployments in ten come up.

The deeper problem is structural: it serves WebSockets and nothing else. A platform health check speaks plain HTTP, so a WebSocket-only process has nothing to answer it with - the deployment is marked unhealthy while working perfectly, or you switch the check off and lose the signal entirely.

Here the WebSocket server is attached to a Node HTTP server. The same port answers GET /health, serves a browser test client, and upgrades connections to WebSocket. On a platform that routes one port per service, that is the shape the app has to have.

## Common Use Cases

- Live updates pushed to a browser - notifications, presence, progress
- A chat or collaboration back end
- A control channel for a dashboard, where polling would be wasteful

## Dependencies for WebSocket Hosting

- Nothing. One service, no database.

### Deployment Dependencies

- ws: https://github.com/websockets/ws
- Source: https://github.com/ak40u/websocket-railway-starter

### Implementation Details

Open the domain: the page connects over wss:// by itself. Open it in a second tab and the two exchange messages. GET /health reports the current connection count, which is a genuinely useful thing to have on a socket server.

Three details worth keeping if you rewrite this:

- **Heartbeat.** Clients disappear without closing the socket - a laptop lid, a dropped mobile connection. Without a ping/pong sweep the server holds those sockets forever and the connection count drifts away from reality.
- **Payloads are capped** at 4 KB before broadcast, so one client cannot push arbitrary volume at everyone else.
- **Shutdown closes sockets with code 1001** before the process exits, so clients reconnect immediately instead of waiting for a timeout to notice.

| Variable | Why |
|---|---|
| PORT | HTTP and WebSocket share it - the platform routes one port |
| HEARTBEAT_MS | Ping interval, default 30000 |

## Scaling note

Broadcast is in-process: a message reaches the clients connected to this instance. With more than one replica you need a shared bus - Redis pub/sub is the usual answer - to fan messages out across them.

## Why Deploy WebSockets on Railway?

TLS on the domain means wss:// works with no extra configuration, and because the health check shares the port, the platform can actually tell whether your socket server is alive.

## Similar templates

- [open-excalidraw](https://railway.com/deploy/open-excalidraw) — Self-hostable collaborative drawing built on Excalidraw
- [caring-vibrancy](https://railway.com/deploy/caring-vibrancy) — Deploy and Host caring-vibrancy with Railway
- [Appsmith](https://railway.com/deploy/appsmith-1) — Low-code platform for internal tools, dashboards, and admin panels.

Open this page in a browser: https://railway.com/deploy/websocket-or-node-server-sharing-one-por
