Deploy to Node.js
Stoma runs natively on Node.js. Deploy to traditional servers, containers, or serverless platforms.
Quick Start
Section titled “Quick Start”-
Install dependencies
Terminal window npm install hono @homegrower-club/stoma @hono/node-server -
Create your gateway
For a minimal example, see the Basic Gateway partial. Here’s a typical production setup with the Node.js adapter:
src/index.ts import {createGateway,cors,requestLog,rateLimit,} from "@homegrower-club/stoma";import { nodeAdapter } from "@homegrower-club/stoma/adapters/node";const gateway = createGateway({name: "my-gateway",basePath: "/api",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", ""),},},},],},// Production adapter with rate limiting and caching supportnodeAdapter());export default gateway.app; -
Create the server entry
src/server.ts import { createServer } from "@hono/node-server";import gateway from "./index";const port = parseInt(process.env.PORT || "3000");createServer({fetch: gateway.fetch,port,}).listen(() => {console.log(`Server running on http://localhost:${port}`);}); -
Run
Terminal window npx tsx src/server.ts
Node.js Adapter
Section titled “Node.js Adapter”For production deployments, use the Node.js adapter:
import { createGateway, cors, rateLimit, cache, circuitBreaker,} from "@homegrower-club/stoma";import { nodeAdapter } from "@homegrower-club/stoma/adapters/node";import { InMemoryMetricsCollector } from "@homegrower-club/stoma";import { metricsReporter } from "@homegrower-club/stoma";
const adapter = nodeAdapter();const metrics = new InMemoryMetricsCollector();
const gateway = createGateway({ name: "my-gateway", basePath: "/api", adapter, policies: [ cors(), metricsReporter({ collector: metrics }), ], routes: [ { path: "/users/*", pipeline: { policies: [ rateLimit({ max: 100, windowSeconds: 60, store: adapter.rateLimitStore, }), ], upstream: { type: "url", target: "https://api.example.com", }, }, }, ],});
export default gateway.app;export { gateway };Server Options
Section titled “Server Options”Using @hono/node-server
Section titled “Using @hono/node-server”Best for simple deployments:
import { createServer } from "@hono/node-server";import gateway from "./index";
const server = createServer({ fetch: gateway.fetch, port: 3000,});
server.listen();Using Express
Section titled “Using Express”For integration with existing Express apps:
import express from "express";import { serve } from "@hono/node-server/serve";import gateway from "./index";
const app = express();
app.use("*", serve({ fetch: gateway.app.fetch }));
app.listen(3000, () => { console.log("Gateway listening on port 3000");});Using Fastify
Section titled “Using Fastify”For better performance:
import Fastify from "fastify";import gateway from "./index";
const fastify = Fastify();
fastify.all("*", async (req, reply) => { const response = await gateway.app.fetch(req.raw, { // Pass any environment variables here }); return response;});
fastify.listen({ port: 3000 });Process Management with PM2
Section titled “Process Management with PM2”Install PM2
Section titled “Install PM2”npm install -g pm2Start the Gateway
Section titled “Start the Gateway”# Start with cluster modepm2 start src/server.ts --name "stoma-gateway" --node-args "-r tsx"
# Or with ecosystem filepm2 start ecosystem.config.jsEcosystem File
Section titled “Ecosystem File”module.exports = { apps: [ { name: "stoma-gateway", script: "src/server.ts", interpreter: "tsx", env: { NODE_ENV: "development", PORT: 3000, }, env_production: { NODE_ENV: "production", PORT: 8080, }, instances: "max", exec_mode: "cluster", watch: false, max_memory_restart: "500M", autorestart: true, restart_delay: 1000, }, ],};PM2 Commands
Section titled “PM2 Commands”# Startpm2 start ecosystem.config.js --env production
# View logspm2 logs stoma-gateway
# Restartpm2 restart stoma-gateway
# Stoppm2 stop stoma-gateway
# Monitorpm2 monitEnvironment Variables
Section titled “Environment Variables”Use environment variables for configuration:
const gateway = createGateway({ name: process.env.GATEWAY_NAME || "my-gateway", basePath: process.env.BASE_PATH || "/api", debug: process.env.DEBUG === "true", // ...});# .env filePORT=8080GATEWAY_NAME=my-gatewayDEBUG=falseJWT_SECRET=your-secretProduction Checklist
Section titled “Production Checklist”- Use a process manager (PM2, systemd)
- Set
NODE_ENV=production - Configure health checks
- Set up logging (JSON format recommended)
- Use environment variables for secrets
- Enable request logging with appropriate log levels
- Configure appropriate timeouts