Skip to content

Hono — full setup

Complete Hono integration for Node or Workers: middleware, outbound fetch, OpenAI, flush on exit.

Install

bash
npm install @amlexiahq/node hono openai

Environment

Node:

env
AMLEXIA_SDK_KEY=am_...
AMLEXIA_INGEST_URL=https://ingest.amlexia.com
AMLEXIA_ENVIRONMENT=production

Cloudflare Workers: bind AMLEXIA_SDK_KEY as a secret — never expose in client bundle.

Node server

typescript
import { Hono } from 'hono';
import { serve } from '@hono/node-server';
import OpenAI from 'openai';
import {
  AmlexiaClient,
  wrapFetch,
  trackOpenAiCompletion,
} from '@amlexiahq/node';
import { amlexiaHonoMiddleware } from '@amlexiahq/node/hono';

const client = new AmlexiaClient({
  sdkKey: process.env.AMLEXIA_SDK_KEY!,
  ingestUrl: process.env.AMLEXIA_INGEST_URL,
  environment: process.env.AMLEXIA_ENVIRONMENT,
});

globalThis.fetch = wrapFetch(client, fetch);
const openai = new OpenAI();

const app = new Hono();

app.use('*', amlexiaHonoMiddleware(client, { serviceName: 'api' }));

app.get('/health', (c) => c.json({ ok: true }));

app.get('/api/users/:id', (c) => c.json({ id: c.req.param('id') }));

app.post('/webhooks/stripe', (c) => c.json({ received: true }));

app.post('/api/chat', async (c) => {
  const body = await c.req.json<{ messages: OpenAI.ChatCompletionMessageParam[] }>();
  const start = Date.now();
  try {
    const completion = await openai.chat.completions.create({
      model: 'gpt-4o-mini',
      messages: body.messages,
    });
    trackOpenAiCompletion(client, {
      model: completion.model,
      statusCode: 200,
      latencyMs: Date.now() - start,
      usage: completion.usage,
    });
    return c.json(completion);
  } catch (e) {
    await client.track({
      endpoint: 'POST /api/chat',
      method: 'POST',
      statusCode: 500,
      latencyMs: Date.now() - start,
      provider: 'openai',
      errorMessage: e instanceof Error ? e.message : 'error',
    });
    return c.json({ error: 'chat failed' }, 500);
  }
});

const server = serve({ fetch: app.fetch, port: 3000 });

process.on('SIGTERM', async () => {
  await client.shutdown();
  process.exit(0);
});

Cloudflare Workers

typescript
import { Hono } from 'hono';
import { AmlexiaClient } from '@amlexiahq/node';
import { amlexiaHonoMiddleware } from '@amlexiahq/node/hono';

type Env = { AMLEXIA_SDK_KEY: string };

const app = new Hono<{ Bindings: Env }>();

app.use('*', async (c, next) => {
  const client = new AmlexiaClient({
    sdkKey: c.env.AMLEXIA_SDK_KEY,
    flushIntervalMs: 1000,
    maxBatchSize: 10,
  });
  c.set('amlexia', client);
  await amlexiaHonoMiddleware(client, { serviceName: 'worker' })(c, next);
  c.executionCtx.waitUntil(client.flush());
});

app.get('/health', (c) => c.json({ ok: true }));

export default app;

Middleware behavior

  • Path normalization (/users/42/users/:id)
  • traceparent header on response
  • Tracks after await next() with final status

Verify

bash
npx amlexia health
curl http://localhost:3000/health