
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
lightrate-express
Advanced tools
Express middleware for LightRate API rate limiting with local token buckets
Express middleware for LightRate API rate limiting with local token buckets. This package provides seamless integration with the LightRate API, automatically throttling requests using local token buckets that refill from the server when needed.
npm install lightrate-express
Or with yarn:
yarn add lightrate-express
const express = require('express');
const { configure, lightrateMiddleware } = require('lightrate-express');
const app = express();
// Step 1: Configure the global client (do this once at startup)
configure({
apiKey: process.env.LIGHTRATE_API_KEY,
applicationId: process.env.LIGHTRATE_APPLICATION_ID
});
// Step 2: Create and apply middleware
const rateLimiter = lightrateMiddleware({
getUserIdentifier: (req) => req.user?.id
});
app.use(rateLimiter);
// Your routes here
app.get('/api/data', (req, res) => {
res.json({ data: 'Your data' });
});
app.listen(3000);
Before using the middleware, you must configure the global LightRate client with your API credentials:
const { configure } = require('lightrate-express');
configure({
// Required: Your LightRate API key
apiKey: process.env.LIGHTRATE_API_KEY,
// Required: Your LightRate Application ID
applicationId: process.env.LIGHTRATE_APPLICATION_ID,
// Optional: Client options
clientOptions: {
// Default size for local token buckets (default: 5)
defaultLocalBucketSize: 10,
// API request timeout in seconds (default: 30)
timeout: 30,
// Number of retry attempts for API requests (default: 3)
retryAttempts: 3
}
});
Each middleware instance can be customized with the following options:
const rateLimiter = lightrateMiddleware({
// Optional: Function to extract user identifier from request
// Defaults to req.user?.id if not provided
getUserIdentifier: (req) => {
return req.user?.id; // or req.headers['x-api-key'], req.ip, etc.
},
// Optional: Custom handler for rate limit exceeded responses
// Defaults to JSON response with 429 status
onRateLimitExceeded: (req, res) => {
res.status(429).json({
error: 'Too Many Requests',
message: 'Rate limit exceeded. Please try again later.'
});
}
});
Apply rate limiting to all routes:
const express = require('express');
const { configure, lightrateMiddleware } = require('lightrate-express');
const app = express();
// Configure the client
configure({
apiKey: process.env.LIGHTRATE_API_KEY,
applicationId: process.env.LIGHTRATE_APPLICATION_ID,
clientOptions: {
defaultLocalBucketSize: 10
}
});
// Create middleware
const rateLimiter = lightrateMiddleware({
getUserIdentifier: (req) => req.user?.id
});
// Apply to all routes
app.use(rateLimiter);
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.listen(3000);
Create different middleware instances for different scenarios:
const express = require('express');
const { configure, lightrateMiddleware } = require('lightrate-express');
const app = express();
// Configure the global client once
configure({
apiKey: process.env.LIGHTRATE_API_KEY,
applicationId: process.env.LIGHTRATE_APPLICATION_ID,
clientOptions: {
defaultLocalBucketSize: 10
}
});
// User-authenticated routes (rate limit by user ID)
const userRateLimiter = lightrateMiddleware({
getUserIdentifier: (req) => req.user?.id,
onRateLimitExceeded: (req, res) => {
res.status(429).json({
error: 'Too Many Requests',
message: 'You have exceeded your rate limit. Please try again later.',
userId: req.user?.id
});
}
});
// API key routes (rate limit by API key)
const apiKeyRateLimiter = lightrateMiddleware({
getUserIdentifier: (req) => req.headers['x-api-key'],
onRateLimitExceeded: (req, res) => {
res.status(429).json({
error: 'API Rate Limit Exceeded',
message: 'Your API key has exceeded its rate limit.',
retryAfter: 60
});
}
});
// Public routes (rate limit by IP address)
const ipRateLimiter = lightrateMiddleware({
getUserIdentifier: (req) => req.ip,
onRateLimitExceeded: (req, res) => {
res.status(429).json({
error: 'Too Many Requests',
message: 'Please slow down your requests.'
});
}
});
// Apply different middleware to different routes
app.use('/api/user/*', userRateLimiter);
app.use('/api/v1/*', apiKeyRateLimiter);
app.use('/api/public/*', ipRateLimiter);
// Or apply to specific routes
app.post('/api/admin/reports', apiKeyRateLimiter, (req, res) => {
res.json({ report: 'data' });
});
app.get('/api/public/status', ipRateLimiter, (req, res) => {
res.json({ status: 'ok' });
});
app.get('/api/user/profile', userRateLimiter, (req, res) => {
res.json({ profile: req.user });
});
app.listen(3000);
import express, { Request, Response } from 'express';
import { configure, lightrateMiddleware, LightrateMiddlewareOptions } from 'lightrate-express';
const app = express();
// Configure the client
configure({
apiKey: process.env.LIGHTRATE_API_KEY!,
applicationId: process.env.LIGHTRATE_APPLICATION_ID!,
clientOptions: {
defaultLocalBucketSize: 10
}
});
// Create middleware with type safety
const middlewareOptions: LightrateMiddlewareOptions = {
getUserIdentifier: (req: Request): string | undefined => {
return req.user?.id;
},
onRateLimitExceeded: (req: Request, res: Response): void => {
res.status(429).json({
error: 'Rate limit exceeded'
});
}
};
const rateLimiter = lightrateMiddleware(middlewareOptions);
app.use(rateLimiter);
app.listen(3000);
The middleware uses a singleton client pattern:
configure() once at application startup to create the global LightRate clientuserIdentifier:path:methodThis ensures:
When a request comes in:
getUserIdentifier()onRateLimitExceeded() handlerThe middleware gracefully handles errors:
This ensures that rate limiting failures don't cause application downtime.
configure(options)Configure the global LightRate client. Must be called before using middleware.
Parameters:
options.apiKey (string, required): Your LightRate API keyoptions.applicationId (string, required): Your LightRate Application IDoptions.clientOptions (object, optional): Client configuration options
defaultLocalBucketSize (number): Default bucket size (default: 5)timeout (number): Request timeout in seconds (default: 30)retryAttempts (number): Number of retry attempts (default: 3)Throws: Error if apiKey or applicationId is missing
lightrateMiddleware(options)Create a LightRate middleware instance.
Parameters:
options.getUserIdentifier (function, optional): Extract user ID from requestoptions.onRateLimitExceeded (function, optional): Custom rate limit handlerReturns: Express middleware function
Throws: Error if global client not configured
reset()Reset the global client configuration. Useful for testing.
getConfiguration()Get the current global configuration.
Returns: Configuration object or null if not configured
interface LightrateConfigureOptions {
apiKey: string;
applicationId: string;
clientOptions?: ClientOptions;
}
interface LightrateMiddlewareOptions {
getUserIdentifier?: (req: Request) => string | undefined;
onRateLimitExceeded?: (req: Request, res: Response) => void;
}
lightrateMiddleware({
getUserIdentifier: (req) => req.user?.id
})
lightrateMiddleware({
getUserIdentifier: (req) => req.headers['x-api-key']
})
lightrateMiddleware({
getUserIdentifier: (req) => req.ip
})
lightrateMiddleware({
getUserIdentifier: (req) => {
// Combine multiple identifiers
return `${req.user?.id}:${req.user?.organizationId}`;
}
})
lightrateMiddleware({
getUserIdentifier: (req) => {
// Skip rate limiting for admin users
if (req.user?.role === 'admin') {
return undefined; // No rate limiting
}
return req.user?.id;
}
})
npm install
npm run build
This creates:
dist/index.js - CommonJS builddist/index.esm.js - ES Module builddist/index.d.ts - TypeScript definitions# Build the package first
npm run build
# Set environment variables
export LIGHTRATE_API_KEY=your_api_key
export LIGHTRATE_APPLICATION_ID=your_app_id
# Run the example
node examples/basic-usage.js
Bug reports and pull requests are welcome on GitHub at https://github.com/lightbourne-technologies/lightrate-client-express.
The package is available as open source under the terms of the MIT License.
FAQs
Express middleware for LightRate API rate limiting with local token buckets
We found that lightrate-express demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.