Node Fetch Cache
node-fetch-cache is a robust wrapper around the popular `node-fetch` library, providing an integrated caching layer for HTTP responses. It automatically caches responses from HTTP requests, serving subsequent identical requests directly from the cache without making a network call. The current stable version is 5.1.0, and the project appears to have an active release cadence with regular updates and maintenance, as indicated by recent releases adding new features like cache clearing. Key differentiators include its seamless integration with the standard `node-fetch` API, support for multiple cache backends (in-memory, file system, Redis via an adapter), and flexible control over caching behavior through `shouldCacheResponse` options. It's designed for Node.js environments, requiring Node.js 18.19.0 or higher, and ships with TypeScript types for improved developer experience.
Common errors
-
TypeError: fetch is not a function
cause Attempting to use `require()` to import `node-fetch-cache` in an environment configured for ESM or when `type: module` is set in `package.json`.fixUse ESM `import fetch from 'node-fetch-cache';` instead of `const fetch = require('node-fetch-cache');`. -
ENOENT: no such file or directory, scandir '/path/to/.node-fetch-cache'
cause The specified `cacheDirectory` for `FileSystemCache` does not exist and the process lacks permissions to create it, or an incorrect path was provided.fixEnsure the `cacheDirectory` path is valid and accessible by the Node.js process. The library should create the directory if it doesn't exist, but permission issues or invalid root paths can prevent this. Check permissions and path correctness.
Warnings
- gotcha By default, `node-fetch-cache` uses an in-memory cache with no Time-To-Live (TTL). This means cached responses will persist indefinitely within the process's lifetime, potentially leading to stale data or excessive memory consumption if not explicitly configured with a `MemoryCache` instance and a `ttl`.
- gotcha When using `FileSystemCache` with a `ttl`, expired cache entries are not automatically deleted from disk. This can lead to significant disk bloat over time as invalid files accumulate in the cache directory.
- breaking `node-fetch-cache` is a wrapper around `node-fetch`. Any breaking changes introduced in major versions of `node-fetch` (e.g., changes to its API or underlying mechanisms) will inherently affect `node-fetch-cache` users. Always review `node-fetch`'s release notes when upgrading.
- gotcha When configuring caching behavior, options passed directly to the `fetch()` call take precedence over options configured via `NodeFetchCache.create()`. This merging behavior might lead to unexpected caching if not understood.
Install
-
npm install node-fetch-cache -
yarn add node-fetch-cache -
pnpm add node-fetch-cache
Imports
- fetch
const fetch = require('node-fetch-cache');import fetch from 'node-fetch-cache';
- NodeFetchCache
import NodeFetchCache from 'node-fetch-cache';
- FileSystemCache
import NodeFetchCache, { FileSystemCache } from 'node-fetch-cache';import { FileSystemCache } from 'node-fetch-cache'; - MemoryCache
import { MemoryCache } from 'node-fetch-cache';
Quickstart
import fetch from 'node-fetch-cache';
import { FileSystemCache } from 'node-fetch-cache';
import * as path from 'path';
async function fetchData() {
// Create a custom fetch instance that caches to disk with a 1-hour TTL
const diskCacheFetch = NodeFetchCache.create({
cache: new FileSystemCache({
cacheDirectory: path.join(process.cwd(), '.node-fetch-cache'),
ttl: 3600000 // 1 hour in milliseconds
}),
shouldCacheResponse: (response) => response.ok // Only cache successful responses
});
console.log('Fetching Google homepage (first time - network request)...');
const firstResponse = await diskCacheFetch('http://google.com');
console.log('Status:', firstResponse.status);
console.log('Cached:', firstResponse.headers.get('x-nf-cache-status')); // Should be 'MISS'
console.log('\nFetching Google homepage (second time - from cache)...');
const secondResponse = await diskCacheFetch('http://google.com');
console.log('Status:', secondResponse.status);
console.log('Cached:', secondResponse.headers.get('x-nf-cache-status')); // Should be 'HIT'
// Demonstrate clearing the cache
const fileCache = new FileSystemCache({ cacheDirectory: path.join(process.cwd(), '.node-fetch-cache') });
console.log('\nClearing file system cache...');
await fileCache.clear();
console.log('Cache cleared. Subsequent fetch will be a MISS again.');
const thirdResponse = await diskCacheFetch('http://google.com');
console.log('Status:', thirdResponse.status);
console.log('Cached:', thirdResponse.headers.get('x-nf-cache-status')); // Should be 'MISS' again
}
fetchData().catch(console.error);