npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tayori/hono

v0.0.1

Published

Hono adapter for Tayori Webhook Router

Readme

@tayori/hono

Hono framework adapter for Tayori webhook router.

Overview

@tayori/hono provides a seamless integration between Tayori's type-safe webhook routing and the Hono web framework. Perfect for edge computing platforms like Cloudflare Workers, Deno, and Bun.

Installation

npm install @tayori/hono @tayori/core hono
# or
pnpm add @tayori/hono @tayori/core hono
# or
yarn add @tayori/hono @tayori/core hono

Note: Both @tayori/core and hono are peer dependencies and must be installed separately.

Features

  • Edge-Ready: Works on Cloudflare Workers, Deno Deploy, Bun, and Node.js
  • Type-Safe: Full TypeScript support with Hono's context types
  • Minimal Overhead: Lightweight adapter with no performance penalty
  • Error Handling: Built-in error handling with customizable error responses
  • Flexible Configuration: Customize success responses and error handling

Quick Start

With Stripe Webhooks

import { Hono } from 'hono';
import Stripe from 'stripe';
import { StripeWebhookRouter, createStripeVerifier } from '@tayori/stripe';
import { honoAdapter } from '@tayori/hono';

const stripe = new Stripe(process.env.STRIPE_API_KEY!);
const router = new StripeWebhookRouter();

router.on('payment_intent.succeeded', async (event) => {
  console.log('Payment succeeded:', event.data.object.id);
});

router.on('customer.subscription.created', async (event) => {
  console.log('New subscription:', event.data.object.id);
});

const app = new Hono();

app.post('/webhook', honoAdapter(router, {
  verifier: createStripeVerifier(stripe, process.env.STRIPE_WEBHOOK_SECRET!),
}));

export default app;

With Custom Webhooks

import { Hono } from 'hono';
import { WebhookRouter, type Verifier } from '@tayori/core';
import { honoAdapter } from '@tayori/hono';

// Define your event types
interface MyEvent extends WebhookEvent {
  type: 'my.event';
  data: { object: { id: string; message: string } };
}

type MyEventMap = {
  'my.event': MyEvent;
};

// Create a custom verifier
const myVerifier: Verifier = (payload, headers) => {
  // Verify signature and parse payload
  const body = JSON.parse(payload.toString());
  return {
    event: {
      id: body.id,
      type: body.type,
      data: { object: body.data },
    },
  };
};

const router = new WebhookRouter<MyEventMap>();

router.on('my.event', async (event) => {
  console.log('Custom event:', event.data.object.message);
});

const app = new Hono();

app.post('/webhook', honoAdapter(router, {
  verifier: myVerifier,
}));

export default app;

API Reference

honoAdapter

Creates a Hono handler from a Tayori webhook router.

function honoAdapter<TEventMap>(
  router: WebhookRouter<TEventMap>,
  options: HonoAdapterOptions
): Handler

Parameters:

  • router - A WebhookRouter instance from @tayori/core
  • options - Configuration options

Returns: A Hono Handler function

HonoAdapterOptions

interface HonoAdapterOptions {
  /**
   * Verifier function for webhook signature validation
   * @required
   */
  verifier: Verifier;

  /**
   * Custom error handler
   * @optional
   */
  onError?: (error: Error, event?: WebhookEvent) => Promise<void> | void;

  /**
   * Custom success response
   * @optional
   * @default { success: true }
   */
  successResponse?: unknown;
}

Advanced Usage

Custom Error Handling

app.post('/webhook', honoAdapter(router, {
  verifier: createStripeVerifier(stripe, secret),
  onError: async (error, event) => {
    // Log to monitoring service
    console.error(`Webhook error for ${event?.type}:`, error);

    // Send to error tracking
    await Sentry.captureException(error, {
      tags: {
        eventType: event?.type,
        eventId: event?.id,
      },
    });
  },
}));

Custom Success Response

app.post('/webhook', honoAdapter(router, {
  verifier: createStripeVerifier(stripe, secret),
  successResponse: {
    status: 'ok',
    processed: true,
    timestamp: Date.now(),
  },
}));

Multiple Webhook Endpoints

const app = new Hono();

// Stripe webhooks
const stripeRouter = new StripeWebhookRouter();
stripeRouter.on('payment_intent.succeeded', async (event) => {
  // Handle payment
});

app.post('/webhooks/stripe', honoAdapter(stripeRouter, {
  verifier: createStripeVerifier(stripe, stripeSecret),
}));

// GitHub webhooks
const githubRouter = new WebhookRouter<GitHubEventMap>();
githubRouter.on('push', async (event) => {
  // Handle push
});

app.post('/webhooks/github', honoAdapter(githubRouter, {
  verifier: createGitHubVerifier(githubSecret),
}));

Platform-Specific Examples

Cloudflare Workers

import { Hono } from 'hono';
import { StripeWebhookRouter, createStripeVerifier } from '@tayori/stripe';
import { honoAdapter } from '@tayori/hono';
import Stripe from 'stripe';

const app = new Hono();
const router = new StripeWebhookRouter();

router.on('payment_intent.succeeded', async (event) => {
  console.log('Payment:', event.data.object.id);
});

app.post('/webhook', honoAdapter(router, {
  verifier: createStripeVerifier(
    new Stripe(process.env.STRIPE_API_KEY!),
    process.env.STRIPE_WEBHOOK_SECRET!
  ),
}));

export default app;

Deno Deploy

import { Hono } from 'https://deno.land/x/hono/mod.ts';
import Stripe from 'npm:stripe';
import { StripeWebhookRouter, createStripeVerifier } from 'npm:@tayori/stripe';
import { honoAdapter } from 'npm:@tayori/hono';

const app = new Hono();
const router = new StripeWebhookRouter();

router.on('charge.succeeded', async (event) => {
  console.log('Charge:', event.data.object.id);
});

app.post('/webhook', honoAdapter(router, {
  verifier: createStripeVerifier(
    new Stripe(Deno.env.get('STRIPE_API_KEY')!),
    Deno.env.get('STRIPE_WEBHOOK_SECRET')!
  ),
}));

Deno.serve(app.fetch);

Bun

import { Hono } from 'hono';
import Stripe from 'stripe';
import { StripeWebhookRouter, createStripeVerifier } from '@tayori/stripe';
import { honoAdapter } from '@tayori/hono';

const app = new Hono();
const router = new StripeWebhookRouter();

router.on('invoice.paid', async (event) => {
  console.log('Invoice:', event.data.object.id);
});

app.post('/webhook', honoAdapter(router, {
  verifier: createStripeVerifier(
    new Stripe(process.env.STRIPE_API_KEY!),
    process.env.STRIPE_WEBHOOK_SECRET!
  ),
}));

export default {
  port: 3000,
  fetch: app.fetch,
};

Error Responses

The adapter automatically returns appropriate HTTP responses:

Success (200 OK)

{
  "success": true
}

Verification Failed (401 Unauthorized)

{
  "error": "Webhook verification failed"
}

Handler Error (500 Internal Server Error)

{
  "error": "Webhook processing failed"
}

Testing

Unit Testing with Hono

import { describe, it, expect } from 'vitest';
import { Hono } from 'hono';
import { StripeWebhookRouter } from '@tayori/stripe';
import { honoAdapter } from '@tayori/hono';

describe('Webhook handler', () => {
  it('processes payment_intent.succeeded events', async () => {
    const router = new StripeWebhookRouter();
    let processed = false;

    router.on('payment_intent.succeeded', async () => {
      processed = true;
    });

    const app = new Hono();
    app.post('/webhook', honoAdapter(router, {
      verifier: mockVerifier,
    }));

    const res = await app.request('/webhook', {
      method: 'POST',
      body: mockPayload,
    });

    expect(res.status).toBe(200);
    expect(processed).toBe(true);
  });
});

Requirements

  • Node.js >= 18 (or Deno, Bun, Cloudflare Workers runtime)
  • TypeScript >= 5.3
  • Hono >= 4.0.0

Related Packages

Documentation

For more examples and guides, see the main documentation.

License

MIT