Skip to content

Getting Started

Installation

Install X511 alongside your framework of choice:

bash
npm install hono x511
bash
npm install elysia x511
bash
npm install next x511
bash
npm install @adonisjs/core x511

X511 ships a dedicated entry point for each supported framework. Import x511 (and the provider factories) from the subpath that matches your framework:

FrameworkImport path
Honox511/hono
Elysiax511/elysia
Next.jsx511/next
AdonisJSx511/adonis

Every adapter re-exports x511, self, zkpassport, and defineProvider, plus the core types (Provider, ProviderContext, X511Config, X511Mode).

Configure

Create an instance with x511(config). The factory returns { verify, verified, config } — two middleware-shaped functions and the resolved configuration.

ts
import { x511, self, zkpassport } from 'x511/hono'

const { verify, verified } = x511({
  domain: 'https://your-app.example.com',
  basePath: '/x511',
  dev: true,
  disclosures: {
    minAge: 18,
  },
  mode: { type: 'session', ttl: 1800 },
  providers: [
    self({ scope: 'your-app', appName: 'Your App' }), 
    zkpassport()
  ],
})

Configuration fields

FieldTypeRequiredDefault
domainstringyes
disclosuresResolvedDisclosuresyes
modeX511Modeyes
providersProvider[]yes
basePathstringno'/'
devbooleannofalse
routesX511Routesno{ sse: '/sse', claim: '/claim' }
pendingTtlnumber (seconds)no600
sessionAdapterSessionAdapternonew MemorySessionAdapter()
  • domain — public origin of your server (no trailing slash). Sent to provider SDKs as the verification endpoint host.
  • basePath — prefix that prefixes every internal route (provider routes, /sse, /claim).
  • dev — when true, the verified cookie omits the Secure flag and provider SDKs target staging environments.
  • mode — cookie strategy. { type: 'session', ttl } keeps the verified cookie alive for ttl seconds. { type: 'one-shot' } issues a 30-second cookie that is consumed (and cleared) on the first verified request.
  • disclosures — what the user must prove. See ResolvedDisclosures.
  • providers — at least one provider built with self(), zkpassport(), or your own defineProvider().
  • pendingTtl — how long an unverified session can remain in the adapter before it is garbage collected.
  • sessionAdapter — pluggable storage. Defaults to in-process memory. See Session storage.

Development mode is OFF by default

Provider SDKs run in production mode unless you explicitly set dev: true. For local development and testing, make sure to enable it — otherwise provider verification flows will target production environments and may not work as expected during development.

Mount and protect

Two pieces wire X511 into your app:

  1. verify — handles every internal X511 route (the provider POST endpoints, /sse, /claim). Mount it once on a path that catches ${basePath}/*.
  2. verified — the gate. Wrap (or attach to) any route that should require an identity proof.

A minimal Hono example, mirroring the layout used by the reference backend in this repo:

ts
import { Hono } from 'hono'
import { x511, self } 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,
  disclosures: { minAge: 18 },
  mode: { type: 'session', ttl: 1800 },
  providers: [self({ scope: 'your-app' })],
})

app.use('*', verify)

app.get('/adults-only', verified, (c) => {
  const identity = c.get('x511')
  return c.text(`Welcome, ${identity?.uniqueId ?? 'anon'}!`)
})

export default app

Visit /adults-only in a browser — you will see the 511 verification page. Scan the QR with the Self app; once the proof clears, the page redirects you back and the route returns the welcome message.

For the equivalent setups on the other frameworks, see Frameworks.

What happens next

  • Use country filtering to restrict accepted nationalities or issuing states.
  • Swap the in-memory session adapter for a Redis-backed one when running multiple server instances.
  • Build custom providers with defineProvider() to support verification systems beyond Self and ZKPassport.