npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

smart-api-throttle

v1.0.0

Published

A lightweight, flexible, frontend-friendly API rate limiter with multiple strategies

Downloads

8

Readme

Smart API Throttle

A lightweight, flexible, frontend-friendly API rate limiter with multiple strategies, universal async wrapper, and React hooks.

Features

  • Multiple Rate Limiting Strategies: Fixed Window, Token Bucket, and Debounce
  • Universal Async Wrapper: Wrap any async function with rate limiting
  • Ready-to-use Adapters: Built-in support for fetch and axios
  • React Hooks: Easy integration with React applications
  • Smart Features: Retry on failure, exponential backoff, request queuing
  • Lightweight: Zero dependencies (except axios for axios adapter)

Installation

npm install smart-api-throttle

Quick Start

Basic Usage

import { SmartThrottle, presets } from 'smart-api-throttle';

// Create a limiter with fixed window strategy
const limiter = new SmartThrottle({
  strategy: 'fixed-window',
  maxRequests: 10,
  windowMs: 60000, // 1 minute
  queue: true,
  retryOnFail: true,
});

// Wrap any async function
const limitedFetch = limiter.wrap(fetch);
const response = await limitedFetch('https://api.example.com/data');

Using Presets

import { SmartThrottle, presets } from 'smart-api-throttle';

// Use predefined configurations
const conservativeLimiter = new SmartThrottle(presets.conservative); // 10 req/min
const moderateLimiter = new SmartThrottle(presets.moderate); // 100 req/min
const tokenBucketLimiter = new SmartThrottle(presets.tokenBucket); // 10 tokens, 1/sec

Rate Limiting Strategies

Fixed Window

Limits requests to X calls per Y milliseconds window.

const limiter = new SmartThrottle({
  strategy: 'fixed-window',
  maxRequests: 100,
  windowMs: 60000, // 100 requests per minute
});

Token Bucket

Implements a token bucket algorithm with configurable capacity and refill rate.

const limiter = new SmartThrottle({
  strategy: 'token-bucket',
  capacity: 10, // Maximum tokens
  refillRate: 1, // 1 token per second
});

Debounce

Waits for a specified delay after the last trigger before allowing execution.

const limiter = new SmartThrottle({
  strategy: 'debounce',
  debounceMs: 500, // 500ms delay
});

Adapters

Fetch Adapter

import { createSmartFetch } from 'smart-api-throttle';

const smartFetch = createSmartFetch({
  strategy: 'fixed-window',
  maxRequests: 10,
  windowMs: 60000,
});

// Use like regular fetch
const response = await smartFetch.fetch('https://api.example.com/data');

// Or use convenience methods
const data = await smartFetch.get('https://api.example.com/users');
const newUser = await smartFetch.post('https://api.example.com/users', {
  name: 'John Doe',
  email: '[email protected]'
});

Axios Adapter

import { createSmartAxios } from 'smart-api-throttle';

const smartAxios = createSmartAxios({
  strategy: 'token-bucket',
  capacity: 10,
  refillRate: 1,
});

// Use like regular axios
const response = await smartAxios.get('https://api.example.com/data');
const newData = await smartAxios.post('https://api.example.com/data', {
  title: 'New Post',
  content: 'Hello World'
});

React Hooks

useSmartFetch

import { useSmartFetch } from 'smart-api-throttle/react';

function MyComponent() {
  const { fetchData, isThrottled, isLoading, error } = useSmartFetch({
    strategy: 'fixed-window',
    maxRequests: 10,
    windowMs: 60000,
  }, {
    onThrottle: (request) => console.log('Request throttled:', request),
    onError: (error) => console.error('Request failed:', error),
  });

  const handleClick = async () => {
    try {
      const response = await fetchData('https://api.example.com/data');
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error('Error:', error);
    }
  };

  return (
    <div>
      <button onClick={handleClick} disabled={isThrottled || isLoading}>
        {isLoading ? 'Loading...' : 'Fetch Data'}
      </button>
      {isThrottled && <p>Rate limited. Please wait...</p>}
      {error && <p>Error: {error.message}</p>}
    </div>
  );
}

useSmartFetchInstance

import { useSmartFetchInstance } from 'smart-api-throttle/react';

function MyComponent() {
  const { fetch, isThrottled, getUsage } = useSmartFetchInstance({
    strategy: 'token-bucket',
    capacity: 10,
    refillRate: 1,
  });

  const handleClick = async () => {
    const response = await fetch('https://api.example.com/data');
    const usage = getUsage();
    console.log('Token bucket usage:', usage);
  };

  return (
    <div>
      <button onClick={handleClick} disabled={isThrottled}>
        Fetch Data
      </button>
      <p>Throttled: {isThrottled ? 'Yes' : 'No'}</p>
    </div>
  );
}

Advanced Features

Request Queuing

const limiter = new SmartThrottle({
  strategy: 'fixed-window',
  maxRequests: 5,
  windowMs: 60000,
  queue: true, // Enable queuing
});

// Requests will be queued when rate limit is exceeded
const promises = Array.from({ length: 10 }, (_, i) =>
  limiter.wrap(fetch)(`https://api.example.com/data/${i}`)
);

// All requests will be processed in order
const responses = await Promise.all(promises);

Retry with Exponential Backoff

const limiter = new SmartThrottle({
  strategy: 'fixed-window',
  maxRequests: 10,
  windowMs: 60000,
  retryOnFail: true,
  maxRetries: 3,
  backoffOn: [429, 503], // Retry on rate limit and service unavailable
});

Custom Callbacks

const limiter = new SmartThrottle({
  strategy: 'fixed-window',
  maxRequests: 10,
  windowMs: 60000,
  onLimitReached: (request) => {
    console.log('Rate limit reached for request:', request);
    // Show user notification, update UI, etc.
  },
  onThrottle: (request) => {
    console.log('Request throttled:', request);
    // Handle throttled request
  },
});

API Reference

SmartThrottle

Constructor

new SmartThrottle(config: RateLimitConfig)

Methods

  • wrap<T, R>(fn: (...args: T) => Promise<R>, ...args: T): Promise<R> - Wrap an async function with rate limiting
  • canExecute(): boolean - Check if a request can be executed
  • getQueueLength(): number - Get the number of queued requests
  • clearQueue(): void - Clear the request queue
  • getUsage(): any - Get current usage statistics (strategy-specific)
  • updateConfig(config: RateLimitConfig): void - Update the limiter configuration

Configuration Options

interface RateLimitConfig {
  strategy: 'fixed-window' | 'token-bucket' | 'debounce';
  maxRequests?: number;        // For fixed-window
  windowMs?: number;           // For fixed-window
  capacity?: number;           // For token-bucket
  refillRate?: number;         // For token-bucket
  debounceMs?: number;         // For debounce
  queue?: boolean;             // Enable request queuing
  retryOnFail?: boolean;       // Enable retry on failure
  maxRetries?: number;         // Maximum retry attempts
  backoffOn?: number[];        // HTTP status codes to trigger backoff
  onLimitReached?: (request: any) => void; // Callback when limit is reached
  onThrottle?: (request: any) => void;     // Callback when request is throttled
}

Testing

# Run tests
npm test

# Run examples
npm run example

# Build package
npm run build

License

MIT