On this page

Node.js HTTP Adapter

The raw Node.js adapter works directly with the built-in http module without any framework.

Installation

npm install @joint-ops/hitlimit
pnpm add @joint-ops/hitlimit
yarn add @joint-ops/hitlimit
bun add @joint-ops/hitlimit

Basic Usage

Use hitlimit with Node.js http server:

server.ts
import { createServer } from 'http'
import { createHitLimit } from '@joint-ops/hitlimit/node'

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

const server = createServer(async (req, res) => {
  const result = await limiter.check(req)

  if (!result.allowed) {
    res.writeHead(429, { 'Content-Type': 'application/json', ...result.headers })
    res.end(JSON.stringify(result.body))
    return
  }

  res.writeHead(200, { 'Content-Type': 'application/json' })
  res.end(JSON.stringify({ message: 'Hello World' }))
})

server.listen(3000)

Custom Key Extraction

Rate limit by custom identifiers:

const limiter = createHitLimit({
  limit: 100,
  window: '1m',
  key: (req) => {
    // Extract API key from header
    return req.headers['x-api-key'] || getClientIp(req)
  }
})

Custom Error Response

Customize the rate limit exceeded response body:

const limiter = createHitLimit({
  limit: 100,
  window: '1m',
  response: (info) => ({
    error: 'Too many requests',
    retryAfter: info.resetIn
  })
})

Using with Stores

Use a persistent store for production:

import { createHitLimit } from '@joint-ops/hitlimit/node'
import { redisStore } from '@joint-ops/hitlimit/stores/redis'

const limiter = createHitLimit({
  limit: 100,
  window: '1m',
  store: redisStore({
    url: 'redis://localhost:6379'
  })
})

Accessing Rate Limit Info

Get detailed rate limit information:

const result = await limiter.check(req)

console.log(result)
// {
//   allowed: true,
//   info: { limit: 100, remaining: 73, resetIn: 45, resetAt: 1640000000, key: '...' },
//   headers: { 'RateLimit-Limit': '100', ... },
//   body: {}
// }

Next Steps