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

hono-usage-limiter

v0.1.1

Published

Credit-based usage limiter for Hono applications

Downloads

582

Readme

Hono Usage Limiter

npm version npm downloads

A credit-based usage limiter for Hono applications. Unlike traditional rate limiters that treat every request equally, this library lets you assign weighted costs to operations and track consumption through a rolling usage bucket with a full audit ledger.

Database-agnostic -- bring your own storage by implementing the UsageStore interface, or use one of the built-in adapters.

Installation

npm install hono-usage-limiter

Quick Start

import { Hono } from "hono";
import { usageManager, type UsageEnv } from "hono-usage-limiter";
import { MemoryStore } from "hono-usage-limiter/memory";

const app = new Hono<UsageEnv>();

app.use(
  usageManager({
    store: new MemoryStore(),
    defaultUsage: 1000,
    defaultWindowDurationMs: 30 * 24 * 60 * 60 * 1000, // 30 days
    keyGenerator: (c) => c.get("userId"),
  }),
);

// Check balance
app.get("/usage", async (c) => {
  const balance = await c.get("usage").getBalance();
  return c.json(balance);
});

// Consume usage
app.post("/inference", async (c) => {
  const usage = c.get("usage");

  const status = await usage.check();
  if (!status.hasUsage) {
    return c.json({ error: "Usage limit exceeded" }, 429);
  }

  // Do expensive work...
  const result = await runInference(input);

  // Deduct actual cost
  await usage.deduct(30, "inference", { inputTokens: 500, outputTokens: 150 });

  return c.json(result);
});

Storage Adapters

MemoryStore

In-memory adapter for testing and prototyping. Data is lost when the process exits.

import { MemoryStore } from "hono-usage-limiter/memory";

const store = new MemoryStore();

UnstorageStore

Adapter backed by unstorage, giving you access to 20+ storage drivers (Redis, Cloudflare KV, filesystem, etc.).

npm install unstorage
import { createStorage } from "unstorage";
import { UnstorageStore } from "hono-usage-limiter/unstorage";

const storage = createStorage(); // or any unstorage driver
const store = new UnstorageStore({ storage });

// With a custom prefix to namespace keys
const store = new UnstorageStore({ storage, prefix: "my-app" });

D1Store

Adapter for Cloudflare D1 (SQLite at the edge). Requires creating two tables in your D1 database:

CREATE TABLE usage_buckets (
  id TEXT PRIMARY KEY,
  owner_id TEXT NOT NULL UNIQUE,
  usage_remaining INTEGER NOT NULL,
  usage_limit INTEGER NOT NULL,
  window_start INTEGER NOT NULL,
  window_duration_ms INTEGER NOT NULL,
  total_consumed INTEGER NOT NULL DEFAULT 0,
  last_consumed_at INTEGER,
  created_at INTEGER NOT NULL,
  updated_at INTEGER NOT NULL
);

CREATE TABLE usage_ledger (
  id TEXT PRIMARY KEY,
  bucket_id TEXT NOT NULL REFERENCES usage_buckets(id) ON DELETE CASCADE,
  owner_id TEXT NOT NULL,
  amount INTEGER NOT NULL,
  reason TEXT NOT NULL,
  metadata TEXT,
  created_at INTEGER NOT NULL
);

CREATE INDEX idx_usage_ledger_bucket ON usage_ledger(bucket_id);
CREATE INDEX idx_usage_ledger_owner ON usage_ledger(owner_id);
npm install @cloudflare/workers-types
import { D1Store } from "hono-usage-limiter/d1";

// In a Cloudflare Worker
const store = new D1Store({ db: env.DB });

// With custom table names
const store = new D1Store({
  db: env.DB,
  bucketsTable: "my_buckets",
  ledgerTable: "my_ledger",
});

Custom Store

Implement the UsageStore interface to use any database:

import type { UsageStore } from "hono-usage-limiter";

class MyStore implements UsageStore {
  getBucket(ownerId) { /* ... */ }
  createBucket(ownerId, options) { /* ... */ }
  updateBucket(bucketId, updates) { /* ... */ }
  deduct(bucketId, ownerId, amount, reason, metadata?) { /* ... */ }
  getLedger(bucketId, cursor?, limit?) { /* ... */ }
}

API

usageManager(config)

Hono middleware that injects a UsageManager onto the context as c.get("usage").

Config options:

| Option | Type | Default | Description | |---|---|---|---| | store | UsageStore | required | Storage adapter | | keyGenerator | (c) => string | required | Resolves owner ID from context | | defaultUsage | number | 1000 | Default usage limit for new buckets | | defaultWindowDurationMs | number | 2592000000 (30 days) | Default rolling window duration | | autoProvision | boolean | true | Auto-create bucket if none exists |

UsageManager

Available via c.get("usage") in your handlers:

| Method | Description | |---|---| | check() | Returns UsageStatus with remaining, limit, hasUsage, resetsAt | | deduct(amount, reason, metadata?) | Deducts usage and records a ledger entry | | getBalance() | Returns full UsageBalanceInfo including totalConsumed and window timestamps | | getHistory(cursor?, limit?) | Returns paginated ledger entries (newest first) | | reset() | Refills usage to the limit and starts a new window | | provision(options) | Creates or updates a bucket with new plan settings |

Contributing

Visit our contributing docs.

License

MIT