Hono
Hono is fetch-native, so the same handler runs on Node, Workers, Deno and Bun.
Only the upgradeWebSocket helper differs per runtime, and you pass it in —
which is the whole reason this adapter is the thinnest of the set.
Install
npm install @luno-oss/core @luno-oss/hono honoPlus the server and WebSocket helpers for your runtime — on Node,
@hono/node-server and @hono/node-ws.
Mount it
Node
import { serve } from '@hono/node-server'
import { createNodeWebSocket } from '@hono/node-ws'
import { Hono } from 'hono'
import { createLuno, memoryStore } from '@luno-oss/core'
import { registerLuno } from '@luno-oss/hono'
const luno = createLuno({
store: memoryStore(),
secret: process.env.LUNO_SECRET!
})
const app = new Hono()
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })
registerLuno(app, { luno, upgradeWebSocket })
const server = serve({ fetch: app.fetch, port: 3000 })
injectWebSocket(server)API
| Export | Purpose |
|---|---|
lunoHono(options) | Returns a standalone Hono app carrying all three routes |
registerLuno(app, options, basePath?) | Mounts that app onto one you already have |
interface LunoHonoOptions {
luno: Luno
upgradeWebSocket: UpgradeWebSocket
paths?: { enroll?: string; enrollStatus?: string; ws?: string }
}Paths default to /enroll, /enroll/status and /ws. Mount under a prefix
with registerLuno(app, options, '/api/luno') — just make sure the URL you
give the node at pairing time matches.
Serving it standalone
import { lunoHono } from '@luno-oss/hono'
const app = lunoHono({ luno, upgradeWebSocket })Use this when Luno is the whole service. Use registerLuno when it is one part
of a larger app.
The REST routes hand c.req.raw — a real Request — straight to
luno.http.handle, with no shim at all. That is the payoff of the core
accepting a structural { method, url, json() }.
Next
- Quickstart — a complete runnable Hono server
- Cloudflare — the Durable Object shape
- Testing — run a fake node against it