Bun Quick Start

Get up and running with hitlimit in Bun in under 5 minutes.

Basic Usage

The simplest way to add rate limiting to a Bun.serve application:

server.ts
import { hitlimit } from '@joint-ops/hitlimit-bun'

const limiter = hitlimit({
  limit: 100,
  window: '1m'
})

Bun.serve({
  port: 3000,
  async fetch(req) {
    const { allowed, remaining, reset } = await limiter.check(req)

    if (!allowed) {
      return new Response('Too Many Requests', {
        status: 429,
        headers: { 'Retry-After': String(reset) }
      })
    }

    return new Response('Hello World!', {
      headers: {
        'X-RateLimit-Remaining': String(remaining)
      }
    })
  }
})

Time Windows

Use human-readable time strings:

hitlimit({ limit: 100, window: '1m' })   // 100 per minute
hitlimit({ limit: 1000, window: '1h' })  // 1000 per hour
hitlimit({ limit: 10000, window: '1d' }) // 10000 per day
hitlimit({ limit: 5, window: '10s' })    // 5 per 10 seconds

Custom Key Extraction

Rate limit by custom identifiers:

custom-key.ts
const limiter = hitlimit({
  limit: 100,
  window: '1m',
  // Rate limit by API key header
  key(req) {
    return req.headers.get('X-API-Key') || getClientIP(req)
  }
})

Using Native SQLite Store

Bun includes native SQLite support. Use it for persistent rate limiting:

sqlite-store.ts
import { hitlimit, bunSqliteStore } from '@joint-ops/hitlimit-bun'

const limiter = hitlimit({
  limit: 100,
  window: '1m',
  store: bunSqliteStore({
    path: './rate-limits.db'
  })
})

Middleware Pattern

Create a reusable rate limiting middleware:

middleware.ts
import { hitlimit } from '@joint-ops/hitlimit-bun'

const limiter = hitlimit({ limit: 100, window: '1m' })

type Handler = (req: Request) => Response | Promise<Response>

function withRateLimit(handler: Handler): Handler {
  return async (req) => {
    const result = await limiter.check(req)

    if (!result.allowed) {
      return new Response(JSON.stringify({
        error: 'Rate limit exceeded',
        retryAfter: result.reset
      }), {
        status: 429,
        headers: { 'Content-Type': 'application/json' }
      })
    }

    return handler(req)
  }
}

export { withRateLimit }

Next Steps