On this page

Bun Quick Start

Using Node.js? See the Node.js Quick Start for @joint-ops/hitlimit.

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'

Bun.serve({
  port: 3000,
  fetch: hitlimit({ limit: 100, window: '1m' }, (req) => {
    return new Response('Hello World!')
  })
})

The hitlimit function wraps your fetch handler. It automatically returns a 429 response when the limit is exceeded, and adds rate limit headers to allowed responses.

Time Windows

Use human-readable time strings:

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

Custom Key Extraction

Rate limit by custom identifiers:

custom-key.ts
Bun.serve({
  port: 3000,
  fetch: hitlimit({
    limit: 100,
    window: '1m',
    // Rate limit by API key header
    key(req) {
      return req.headers.get('X-API-Key') || 'anonymous'
    }
  }, (req) => {
    return new Response('Hello World!')
  })
})

Using Native SQLite Store

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

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

Bun.serve({
  port: 3000,
  fetch: hitlimit({
    limit: 100,
    window: '1m',
    store: sqliteStore({
      path: './rate-limits.db'
    })
  }, (req) => {
    return new Response('Hello World!')
  })
})

Manual Check Pattern

For more control, use createHitLimit to manually check rate limits per route:

manual-check.ts
import { createHitLimit } from '@joint-ops/hitlimit-bun'

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

Bun.serve({
  port: 3000,
  async fetch(req, server) {
    // Returns a 429 Response if blocked, or null if allowed
    const blocked = await limiter.check(req, server)
    if (blocked) return blocked

    // Handle request normally
    return new Response('Hello World!')
  }
})

Next Steps