A tiny, dependency-free retry utility with fixed delay or built-in exponential backoff, designed for predictable behavior in modern TypeScript applications.
🚨 Async-only support
executeWithRetries supports only async callbacks (functions that return a Promise).
Synchronous functions are not supported and must be wrapped in an async function if needed.
npm install execute-with-retries- Zero dependencies
- No side effects (no logging by default)
- Functional (not class-based)
- Works in both client-side and server-side JavaScript environments
- Preset Default and tiny configuration surface
- Async-only by design
- No hooks, no events, no middleware
executeWithRetries<T>(
callback: () => Promise<T>, /* arguments are not passed directly; use closures instead */
options?: {
retries?: number;
delay?: {
type: "fixed" | "exponential";
ms: number;
};
}
): Promise<T>- Basic Usage: Retrying an Operation
import { executeWithRetries } from 'execute-with-retries';
const apiResponse = await executeWithRetries(async () => {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error('Request failed');
} else {
return response.json();
}
});
/*
Note: Default Settings:
Retries: 3 Nos
delay = { type: "fixed", ms: 300 }
*/- Custom Retry Count Param
import { executeWithRetries } from 'execute-with-retries';
const apiResponse = await executeWithRetries(
async () => {
const response = await fetch('https://api.example.com/data');
return response;
},
{ retries: 5 },
);
/* Note: Retries the operation up to 5 times before failing. */- Fixed Delay Between Retries
import { executeWithRetries } from "execute-with-retries";
const apiResponse = await executeWithRetries(async () => {
const response = await fetch("https://api.example.com/data");
return response;
}, {retries: 3, delay: {type: "fixed", ms: 1000}});
/* Note: Waits 1 second between each retry attempt.- Exponential Backoff Implementation
import { executeWithRetries } from 'execute-with-retries';
const apiResponse = await executeWithRetries(
async () => {
const response = await fetch('https://api.example.com/data');
return response;
},
{ retries: 3, delay: { type: 'exponential', ms: 500 } },
);
/* Note: Delay Pattern:
First Attempt: 500ms
Second Attempt: 1000ms
Third Attempt: 2000ms
...and so on.
*/- Passing Data via a Top-Level Function
import { executeWithRetries } from "execute-with-retries";
async function getUserDetails(userId: number): Promise<Record<string, any>> {
return executeWithRetries(async () => {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error("Failed to fetch user");
} else {
return await response.json();
}
});
}
const userInfo = await getUserDetails(100);PASS src/execute-with-retries/test/index.test.ts
executeWithRetries
✓ resolves on first attempt without retries
✓ retries failures and resolves when a later attempt succeeds
✓ throws immediately when retries is set to 0
✓ throws after all retry attempts fail
PASS src/execute-with-retries/test/calculate-delay.test.ts
calculateDelayMs
✓ returns fixed delay milliseconds for fixed type
✓ computes exponential delay based on attempt
✓ caps exponential delay at 10000ms
--------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------|---------|----------|---------|---------|-------------------
All files | 98.41 | 94.11 | 100 | 98.41 |
calculate-delay.ts | 100 | 100 | 100 | 100 |
index.ts | 97.43 | 92.85 | 100 | 97.43 | 28
--------------------|---------|----------|---------|---------|-------------------
Contributions, suggestions, and improvements are welcome.
Feel free to open issues or pull requests.
Like this project? Support it with a github star, it would mean a lot to me! Cheers and Happy Coding.
