Hono
npm install hono x511Full example
import { serve } from '@hono/node-server'
import { Hono } from 'hono'
import { x511, self, zkpassport } from 'x511/hono'
declare module 'hono' {
interface ContextVariableMap {
x511: { uniqueId?: string }
}
}
const app = new Hono()
const { verify, verified } = x511({
domain: 'https://your-app.example.com',
basePath: '/x511',
dev: true,
mode: { type: 'session', ttl: 1800 },
disclosures: {
minAge: 18,
nationality: { excluded: ['RUS'] },
},
providers: [
self({ scope: 'self-playground', appName: 'Backend Demo' }),
zkpassport(),
],
})
app.use('*', verify)
app.get('/home', verified, (c) => {
const identity = c.get('x511')
return c.text(identity?.uniqueId ?? 'anon')
})
serve({ fetch: app.fetch, port: 8000 })Mounting
verify is a Hono middleware. Mount it once on '*' (or any prefix that catches ${basePath}/*); it short-circuits when the request matches an internal X511 route and calls next() otherwise.
app.use('*', verify)verified is the route gate. Attach it as middleware on any route that should require an identity proof:
app.get('/adults-only', verified, handler)
app.use('/api/admin/*', verified) // protect a whole subtreeWhen the cookie is valid, verified calls c.set('x511', { uniqueId }) and continues; otherwise it sets status 511 and returns the verification HTML page.
Reading the identity
declare module 'hono' {
interface ContextVariableMap {
x511: { uniqueId?: string }
}
}
app.get('/me', verified, (c) => {
const { uniqueId } = c.get('x511') ?? {}
return c.json({ uniqueId })
})Augmenting ContextVariableMap is the standard Hono pattern for typing c.get() / c.set(). Without it, c.get('x511') widens to unknown.
Tips
- Middleware ordering — register
verifybefore any handler that depends onbasePath-prefixed routes; otherwise an unrelated handler may match first. - Selective protection — call
verifiedper route or per subtree rather than globally. The 511 page assumes the request is a navigation; mountingverifiedglobally on JSON-only APIs gives clients the HTML page when they expected JSON. - Custom error responses —
verifiedalways returns the HTML page on failure. If your route is API-only, gate access manually with the corecoreVerifiedreturned from thex511/coreentry point.
Native Request required
Internally the Hono adapter reads c.req.raw, which must be a native WinterTC-compatible Request instance. Hono on Bun, Deno, Cloudflare Workers, Node (via @hono/node-server), and Vercel Edge all satisfy this — no extra work needed.