Deploy with Node.js
Deploy your Stoma gateway on Node.js using @hono/node-server, Hono’s official Node.js adapter.
Quick Start
Section titled “Quick Start”-
Install dependencies
Terminal window npm install hono @hono/node-server @vivero/stoma -
Create your gateway
src/index.ts import { serve } from "@hono/node-server";import {createGateway,cors,requestLog,rateLimit,} from "@vivero/stoma";import { nodeAdapter } from "@vivero/stoma/adapters/node";const gateway = createGateway({name: "my-gateway",basePath: "/api",adapter: nodeAdapter(),policies: [requestLog(), cors()],routes: [{path: "/users/*",pipeline: {policies: [rateLimit({ max: 100, window: 60 })],upstream: {type: "url",target: "https://api.example.com",rewritePath: (path) => path.replace("/api", ""),},},},],});serve({ fetch: gateway.app.fetch, port: 3000 }, (info) => {console.log(`Gateway listening on http://localhost:${info.port}`);}); -
Run
Terminal window npx tsx src/index.ts
Node Adapter
Section titled “Node Adapter”The nodeAdapter() provides in-memory stores for rate limiting, circuit breakers, and caching. It delegates to memoryAdapter() under the hood.
import { serve } from "@hono/node-server";import { createGateway, cors, rateLimit, cache,} from "@vivero/stoma";import { nodeAdapter } from "@vivero/stoma/adapters/node";
const adapter = nodeAdapter();
const gateway = createGateway({ name: "my-gateway", basePath: "/api", adapter, policies: [cors()], routes: [ { path: "/users/*", pipeline: { policies: [ rateLimit({ max: 100, windowSeconds: 60, store: adapter.rateLimitStore, }), ], upstream: { type: "url", target: "https://api.example.com", }, }, }, ],});
serve({ fetch: gateway.app.fetch, port: 3000 }, (info) => { console.log(`Gateway listening on http://localhost:${info.port}`);});Server Options
Section titled “Server Options”Basic Server
Section titled “Basic Server”import { serve } from "@hono/node-server";import gateway from "./gateway";
serve({ fetch: gateway.app.fetch, port: 3000 }, (info) => { console.log(`Listening on http://localhost:${info.port}`);});With TLS/HTTPS
Section titled “With TLS/HTTPS”import { readFileSync } from "node:fs";import { serve } from "@hono/node-server";import gateway from "./gateway";
serve({ fetch: gateway.app.fetch, port: 443, createServer: await import("node:https").then((m) => m.createServer), serverOptions: { cert: readFileSync("./cert.pem"), key: readFileSync("./key.pem"), },});With Unix Socket
Section titled “With Unix Socket”For reverse proxy integration (nginx, Caddy):
import { createServer } from "node:http";import { serve } from "@hono/node-server";import gateway from "./gateway";
const server = serve({ fetch: gateway.app.fetch, createServer,});
server.listen("/tmp/gateway.sock");Platform Deployment
Section titled “Platform Deployment”Railway
Section titled “Railway”{ "scripts": { "build": "tsc", "start": "node dist/index.js" }}Render
Section titled “Render”services: - type: web runtime: node buildCommand: npm ci && npm run build startCommand: node dist/index.js envVars: - key: NODE_ENV value: productionFly.io
Section titled “Fly.io”app = "stoma-gateway"
[build] builder = "heroku/buildpacks:22"
[env] NODE_ENV = "production" PORT = "3000"
[[services]] internal_port = 3000 protocol = "tcp"
[[services.ports]] port = 80 handlers = ["http"]
[[services.ports]] port = 443 handlers = ["tls", "http"]Environment Variables
Section titled “Environment Variables”const gateway = createGateway({ name: process.env.GATEWAY_NAME || "my-gateway", basePath: process.env.BASE_PATH || "/api", debug: process.env.DEBUG === "true",});
serve({ fetch: gateway.app.fetch, port: parseInt(process.env.PORT || "3000"),});GATEWAY_NAME=my-gatewayPORT=3000DEBUG=falseNext Steps
Section titled “Next Steps” Deploy with Docker Containerize your Node.js gateway
Deploy to Cloudflare Deploy to the edge for global low latency