Retry async functions with exponential backoff. Same API as p-retry, but ships both ESM and CJS with zero dependencies.
import { pRetry } from "tiny-pretry";
const data = await pRetry(
() => fetch("https://api.example.com/data").then((r) => r.json()),
{ retries: 3 },
);~800 bytes gzipped. Zero dependencies. Replaces p-retry without the ESM-only headache.
Demo built with remotion-readme-kit
npm install tiny-pretryimport { pRetry } from "tiny-pretry";
const result = await pRetry(
async (attemptNumber) => {
console.log(`Attempt ${attemptNumber}`);
const res = await fetch("https://api.example.com");
if (!res.ok) throw new Error(res.statusText);
return res.json();
},
{ retries: 5 },
);import { pRetry, AbortError } from "tiny-pretry";
await pRetry(
async () => {
const res = await fetch("https://api.example.com");
if (res.status === 401) {
throw new AbortError("Not authorized, retrying won't help");
}
return res.json();
},
{ retries: 5 },
);await pRetry(doWork, {
retries: 5,
onFailedAttempt: (error) => {
console.log(
`Attempt ${error.attemptNumber} failed. ${error.retriesLeft} retries left.`,
);
},
});const controller = new AbortController();
setTimeout(() => controller.abort(), 10000);
await pRetry(unreliableCall, {
retries: 10,
signal: controller.signal,
});p-retry v6+ is ESM-only. If you require("p-retry") in a CommonJS project, you get ERR_REQUIRE_ESM. tiny-retry works with both import and require().
p-retry |
tiny-retry |
|
|---|---|---|
| CJS support | v5 only (v6+ ESM-only) | ESM + CJS |
| Dependencies | retry, is-network-error |
0 |
| TypeScript | separate @types | native |
| Export | default | named |
- import pRetry from "p-retry";
+ import { pRetry } from "tiny-pretry";One line. Everything else stays the same.
Retries fn until it succeeds or retries are exhausted.
fn(attemptNumber)- function to retry (attempt starts at 1)options.retries- max retries (default:10)options.factor- exponential factor (default:2)options.minTimeout- initial delay in ms (default:1000)options.maxTimeout- max delay cap in ms (default:Infinity)options.randomize- add jitter to delays (default:false)options.signal-AbortSignalfor cancellationoptions.onFailedAttempt(error)- called after each failure
Throw new AbortError(message) or new AbortError(error) inside fn to stop retrying immediately.
The error passed to onFailedAttempt has two extra properties:
attemptNumber- which attempt just failed (1-based)retriesLeft- how many retries remain
Drop-in replacements for sindresorhus async utilities. All ship ESM + CJS with zero dependencies.
| Package | Replaces | What it does |
|---|---|---|
| tiny-limit | p-limit | Concurrency limiter |
| tiny-map | p-map | Concurrent map with order |
| tiny-retry | p-retry | Retry with exponential backoff |
| tiny-queue | p-queue | Priority task queue |
| tiny-ms | ms | Parse/format durations |
| tiny-escape | escape-string-regexp | Escape regex chars |
Want all async utilities in one import? Use tiny-pasync.
If this saved you from ERR_REQUIRE_ESM, star the repo or open an issue if something breaks.
README built with README Builder
