gobouncer
v0.1.0
Published
Drop-in rate limiting middleware for Node.js, backed by the GoBouncer Go service.
Maintainers
Readme
gobouncer
Drop-in rate limiting middleware for Node.js, backed by the GoBouncer Go service.
GoBouncer itself runs as a small, fast Go service backed by Redis. This package is a thin client — it does no rate limiting math itself, it just talks to your running GoBouncer instance over HTTP and gives you an Express-style middleware.
Install
npm install gobouncerRequires Node.js 18+ (uses the built-in fetch).
Quick start
import express from 'express'
import { gobouncer } from 'gobouncer'
const app = express()
// Create once, reuse everywhere
const limiter = gobouncer({ url: 'http://localhost:8080' })
// Apply globally — 100 requests per minute per IP
app.use(limiter.limit({ max: 100, windowMs: 60_000 }))
// Stricter limit on a sensitive route
app.post('/login', limiter.limit({ max: 5, windowMs: 60_000 }), loginHandler)
// Limit by authenticated user instead of IP
app.post(
'/api/ai/generate',
limiter.limit({
max: 10,
windowMs: 60_000,
key: (req) => `user:${req.user.id}`,
algorithm: 'gcra',
}),
generateHandler
)
app.listen(3000)API
gobouncer(options)
Creates a client.
| Option | Type | Default | Description |
| ----------- | --------- | ---------------- | -------------------------------------------------------- |
| url | string | — | Base URL of your running GoBouncer service |
| timeoutMs | number | 150 | Max time to wait for a response |
| failOpen | boolean | true | Allow requests through if GoBouncer is unreachable |
| apiKey | string | — | Optional shared secret sent as X-GoBouncer-Key |
limiter.limit(options)
Returns an Express-style middleware (req, res, next) => void.
| Option | Type | Default | Description |
| ----------- | --------------------- | ------------------- | --------------------------------------------- |
| max | number | — | Max requests allowed per window |
| windowMs | number | — | Window size in milliseconds |
| key | (req) => string | limits by client IP | How to identify the caller |
| algorithm | 'sliding_window' | 'gcra' | 'sliding_window' | Which algorithm GoBouncer should use |
limiter.check(key, max, windowMs, algorithm?)
Call GoBouncer directly without the middleware wrapper — useful for protecting non-HTTP code paths, like before enqueuing a BullMQ job:
const result = await limiter.check(`enqueue:${userId}`, 10, 60_000)
if (!result.allowed) {
throw new Error(`queue limit reached, retry in ${result.retry_after}ms`)
}
await emailQueue.add('send', jobData)Built-in key helpers
import { ipKey, headerKey } from 'gobouncer'
limiter.limit({ max: 100, windowMs: 60_000, key: ipKey })
limiter.limit({ max: 100, windowMs: 60_000, key: headerKey('X-API-Key') })Behaviour when GoBouncer is unreachable
By default (failOpen: true), requests pass through if GoBouncer can't be reached within timeoutMs. This means a GoBouncer outage degrades your app to "no rate limiting" instead of "app is down." Set failOpen: false if strict enforcement matters more than availability for your use case.
License
MIT #� �g�o�b�o�u�n�c�e�r�-�p�a�c�k�a�g�e� � �
