Framework Quickstarts
Hono quickstart
Build an edge-ready API with Hono that publishes and receives npayload messages
Build an edge-ready API with Hono that publishes messages to npayload and receives webhooks. Hono runs on edge runtimes, Bun, Deno, and Node.js.
Prerequisites
- Node.js 18+ or Bun
- An npayload account with machine credentials (get them here)
Set up the project
mkdir npayload-hono && cd npayload-hono
npm init -y
npm install @npayload/node hono
npm install -D typescript tsx @types/nodemkdir npayload-hono && cd npayload-hono
bun init
bun add @npayload/node honoCreate a .env file:
NPAYLOAD_CLIENT_ID=oac_your_client_id
NPAYLOAD_HMAC_SECRET=your_hmac_secret
WEBHOOK_SECRET=your_webhook_secret
PORT=3000Create the npayload client
// src/npayload.ts
import { NPayloadAuth, NPayloadClient } from '@npayload/node';
const auth = new NPayloadAuth({
clientId: process.env.NPAYLOAD_CLIENT_ID!,
hmacSecret: process.env.NPAYLOAD_HMAC_SECRET!,
});
export const npayload = new NPayloadClient({
auth,
environment: 'development',
});Set up channels
// src/setup.ts
import { npayload } from './npayload';
export async function setup() {
await npayload.channels.create({
name: 'events',
description: 'Application events',
privacy: 'standard',
});
await npayload.subscriptions.create({
channel: 'events',
name: 'event-handler',
type: 'webhook',
endpoint: {
url: `${process.env.BASE_URL ?? 'http://localhost:3000'}/webhooks/events`,
method: 'POST',
},
});
console.log('Channel and subscription created.');
}Build the Hono app
// src/index.ts
import { Hono } from 'hono';
import { serve } from '@hono/node-server';
import { npayload } from './npayload';
import { setup } from './setup';
const app = new Hono();
// Publish endpoint
app.post('/publish', async (c) => {
const body = await c.req.json();
const message = await npayload.messages.publish({
channel: 'events',
payload: body,
});
return c.json({ messageId: message.gid }, 201);
});
// Webhook receiver
app.post('/webhooks/events', async (c) => {
const body = await c.req.json();
const signature = c.req.header('x-npayload-signature') ?? '';
const isValid = npayload.webhooks.verify(
body,
signature,
process.env.WEBHOOK_SECRET!
);
if (!isValid) {
return c.json({ error: 'Invalid signature' }, 401);
}
console.log('Received:', body.payload);
return c.json({ received: true });
});
// Health check
app.get('/health', (c) => c.json({ status: 'ok' }));
const port = Number(process.env.PORT) || 3000;
setup().then(() => {
serve({ fetch: app.fetch, port }, () => {
console.log(`Hono server running on port ${port}`);
});
});Run it
npx tsx src/index.tsbun run src/index.tsTest publishing:
curl -X POST http://localhost:3000/publish \
-H "Content-Type: application/json" \
-d '{"event": "item.purchased", "itemId": "itm_456", "quantity": 2}'Next steps
- Bun quickstart for a Bun-native server
- Node.js SDK for the full API reference
- Webhooks guide for production webhook patterns
Was this page helpful?