AbortController lets you cancel fetch requests and timers. It was added natively to Node.js in v15. If you are on Node 14 or older, you will see ReferenceError: AbortController is not defined. Two paths: upgrade Node, or polyfill with the abort-controller package.

Step 1: Check your Node version
node --version
# v15+ has built-in AbortController as global
# v15-v17.2 = AbortController, no AbortSignal.timeout()
# v17.3+ = AbortSignal.timeout() helper added
Fix 1: Upgrade Node to v18 or v20 LTS
nvm install 20
nvm use 20
// Now this works without imports:
const controller = new AbortController();
fetch('https://api.github.com', { signal: controller.signal });
setTimeout(() => controller.abort(), 5000);
Fix 2: Polyfill with abort-controller (Node 14 or older)
npm install abort-controller
import AbortController from 'abort-controller';
// or const AbortController = require('abort-controller');
const controller = new AbortController();
Fix 3: AbortSignal.timeout() shortcut (Node 17.3+)
// Cancel fetch after 5 seconds:
const res = await fetch('https://api.github.com', {
signal: AbortSignal.timeout(5000)
});
// Combine multiple signals (Node 19+):
AbortSignal.any([signal1, AbortSignal.timeout(5000)]);
Full example: cancellable fetch with timeout
async function fetchWithTimeout(url, timeoutMs = 5000) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
try {
const res = await fetch(url, { signal: controller.signal });
return await res.json();
} catch (err) {
if (err.name === 'AbortError') {
throw new Error(`Request timed out after ${timeoutMs}ms`);
}
throw err;
} finally {
clearTimeout(timeout);
}
}
Frequently Asked Questions
What is AbortController used for?
Canceling in-flight async operations: fetch requests, file reads, streams, custom long-running promises. Pass controller.signal to the operation; calling controller.abort() rejects the operation with an AbortError.
When was AbortController added to Node.js?
Available behind –experimental flag in v14.17, stable in v15.0 (October 2020), no flag needed since v15. AbortSignal.timeout() helper added in v17.3 (December 2021).
Should I use AbortSignal.timeout or new AbortController?
For pure timeout, AbortSignal.timeout(5000) is shorter. For user-driven cancel (e.g., “Cancel” button), use AbortController so you can call abort() yourself. Combine both with AbortSignal.any() in Node 19+.
Does axios support AbortController?
Yes since v0.22. Pass signal: controller.signal in the axios config. Cancels in-flight requests with AbortError (replaces the old CancelToken pattern).
How do I cancel a setInterval or async loop?
Pass the signal and check signal.aborted: if (signal.aborted) return; or use signal.addEventListener(‘abort’, cleanup). For setInterval, store the id and clearInterval() inside the abort listener.
