New in v0.4.0

Edge & Runtime Support

The TypeScript SDK's core is edge-safe zero Node built-ins. Run the limiter on Cloudflare Workers, Deno, Bun, and Vercel Edge alongside Node.

Edge-safe core

Limiter, algorithms, InMemoryStore, extractors, presets, OTel adapter all use zero Node built-ins.

RedisStore is Node-only

ioredis needs TCP. For edge distributed limits, inject a fetch-based REST client satisfying RedisClientLike.

Dual ESM + CJS

Both module formats with per-condition type declarations across every adapter entrypoint.

What works where

RuntimeLimiter coreInMemoryStoreRedisStore
Node.js
Bun
Deno
Cloudflare Workers
Vercel Edge

Distributed limits on the edge

The packaged RedisStore talks to ioredis over TCP, which isn't available on most edge runtimes. The store is decoupled from the client through the RedisClientLike interface pass any object that satisfies it and the Lua scripts run unchanged. The easiest path on Cloudflare Workers and Vercel Edge is the Upstash REST client:

Upstash REST clientbash
npm install @upstash/redis
import { Redis } from '@upstash/redis';
import { RateLimiter, RedisStore, presets } from 'halt-rate';

// Upstash exposes a fetch-based client that's safe on edge runtimes.
const upstash = Redis.fromEnv();

// A thin adapter satisfying RedisClientLike (eval / get / set / etc).
const client = {
  eval: (script: string, keys: string[], args: (string | number)[]) =>
    upstash.eval(script, keys, args),
  // …add the few other methods RedisClientLike needs for your algorithms
};

const store = new RedisStore({ client });
const limiter = new RateLimiter({ store, policy: presets.PUBLIC_API });

See RedisStore docs for the full interface shape, fail-open behaviour, and metrics.

Hono on Cloudflare Workers

The new Hono adapter derives the client IP from edge headers (x-forwarded-for / cf-connecting-ip / x-real-ip) out of the box. Override with getClientIp for custom edge proxies.

import { Hono } from 'hono';
import { RateLimiter, InMemoryStore, presets } from 'halt-rate';
import { haltMiddleware } from 'halt-rate/hono';

const limiter = new RateLimiter({ store: new InMemoryStore(), policy: presets.PUBLIC_API });
const app = new Hono();
app.use('*', haltMiddleware({ limiter }));

export default app;

ESM + CJS

The package ships dual builds with proper exports conditions and types per entrypoint halt-rate, halt-rate/express, halt-rate/next, halt-rate/hono, halt-rate/fastify, and halt-rate/graphql all resolve in both ESM and CommonJS projects with no extra config.