A tiny, dependency-free Node.js client for searching public US recall APIs. First published in 2014. Modernized to v2.0.0 in 2026. The 12-year gap is the point.
recollie is a small client library for querying public US recall APIs. You give it a search term; it returns the matching recall records from the upstream API.
It is also a personal artifact. The first version shipped to npm in 2014, when I was learning JavaScript and building tooling around full-stack work that predated the agentic-AI era. v2.0.0 shipped in 2026 as a deliberate exercise in maintaining useful developer tooling across a long gap.
The library has stayed honest about what it is the whole time:
- One thing it does well: query public recall data
- Zero runtime dependencies
- Small, readable, typed surface area
- Node 18+ baseline, native
fetch(nonode-fetchdependency) - TypeScript declarations shipped with the package
- Structured errors (
RecollieError) with stable, machine-readable error codes - New default data source. Early versions queried the old USA.gov aggregate recall endpoint, which is no longer active; v2.0.0 defaults to the CPSC recalls API
- Continuous integration on push and PR (Node 18, 20, 22)
- Same zero-runtime-dependency promise as v1
npm install recollieconst recollie = require('recollie');
// Searches the CPSC recalls API (the default) by product name.
const recalls = await recollie('crib', { limit: 5 });
for (const recall of recalls) {
console.log(recall.Title);
}The named search export is identical to the default call:
const { search } = require('recollie');
const recalls = await search('crib');const recalls = await recollie(term, options);term is a required, non-empty string. options is optional:
| Option | Default | Description |
|---|---|---|
endpoint |
CPSC recalls API | API endpoint URL. |
queryParam |
"ProductName" |
Query parameter used for the search term. |
queryPrefix |
"" |
Prefix added before the term for fielded-search APIs. |
params |
{} |
Extra query parameters (values are stringified). |
limit |
25 |
Local cap for array or { results: [] } responses. null disables. |
timeoutMs |
10000 |
Request timeout in milliseconds. |
headers |
{} |
Additional request headers. |
fetch |
globalThis.fetch |
Custom fetch implementation (for tests or non-standard runtimes). |
recollie returns the parsed JSON from the upstream API, optionally length-limited. The shape is whatever the endpoint returns — the library does not normalize it.
The endpoint is configurable, so the same client works against other recall APIs. For example, openFDA food enforcement uses search=product_description:<term>:
const results = await recollie('peanut butter', {
endpoint: 'https://api.fda.gov/food/enforcement.json',
queryParam: 'search',
queryPrefix: 'product_description:',
params: { limit: 5 },
limit: 5,
});Error-first callbacks are supported, and the legacy success-only callback still works:
recollie('crib', { limit: 5 }, (error, recalls) => {
if (error) return console.error(error);
console.log(recalls);
});Prefer the Promise API or error-first callbacks for new code so failures are explicit.
Operational failures reject with a RecollieError carrying a stable code:
FETCH_UNAVAILABLE · HTTP_ERROR · INVALID_JSON · REQUEST_FAILED · TIMEOUT
HTTP_ERROR also carries status and body. Invalid caller input (such as an empty term) throws a TypeError.
try {
await recollie('crib');
} catch (error) {
if (error instanceof recollie.RecollieError) {
console.error(error.code, error.status);
}
}- Zero runtime dependencies. A package that has lived more than a decade in npm has watched a lot of dependencies disappear. This one doesn't have any to lose.
- Native
fetchonly. Node 18+ is the floor. - Server-only. This is a Node library, not a browser library. CORS for these public APIs is variable and not worth pretending to abstract over.
- No magic retries. You get a configurable
timeoutMsand can supply your ownfetch; the retry policy is the caller's to choose.
I keep this package alive for one reason: it is a verifiable, third-party-hosted (npm registry) record of writing and maintaining production code across a long horizon. That matters more to me than the size of the user base. If it helps you find a recall faster, that is a bonus.
| Role | Project |
|---|---|
| This repo | recollie — npmjs.com/package/recollie |
| Author's GitHub profile | github.com/roymcfarland |
| Other public infra repos | Atlas Beta Bug Reporter · Workflow Blueprint · Agentic Daily Digest · Builder & Verifier methodology |
- Default: CPSC recalls API
- Example: openFDA food enforcement API
Recall data can change and may be incomplete. Verify safety-critical decisions with the responsible agency or manufacturer.
Semantic versioning. v1.x is preserved on npm for historical reference. v2.0.0 introduces TypeScript declarations, structured errors, and a new default data source as breaking changes against the v1 surface; everything else attempts to remain familiar.
MIT.
Roy McFarland — brightline.io · roy@brightline.io