request-promise

A Bluebird-powered Promise wrapper around the request HTTP client for Node.js — deprecated since 2020 along with request itself.

Library
npm
v4.2.6
4,716stars
ISC

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
42/100Fair
Development Activity0
Maintenance0
Community68
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
56/100Fair
Architecture65
Code Quality65
Innovation40
Learning Curve55

request-promise bolts Bluebird promise support onto the request HTTP client, giving callers .then(), .catch(), .finally(), .cancel(), and .promise() on top of the same options object request already accepts. It was one of the most widely used HTTP clients in the Node.js ecosystem during the pre-native-fetch, pre-async/await-friendly-client era, and its download numbers (still over a million a week) reflect how deeply it got baked into legacy codebases rather than ongoing new adoption.

Both request-promise and its peer dependency request were formally deprecated in February 2020 — request because Node’s ecosystem moved to promise-first clients and the maintainers stopped shipping fixes, and request-promise because it depends entirely on request under the hood. The README itself carries a deprecation notice pointing users toward request-promise-native (no Bluebird dependency, native ES6 promises) or, more commonly today, axios, got, or the built-in fetch API. Projects still depending on it should treat it as a maintenance liability: no security patches are forthcoming for either package, and migration off it is a one-way improvement, not a nice-to-have.

What You Get

  • Drop-in promise support for any request(options, callback) call, by simply swapping the require and dropping the callback
  • Bluebird-powered .then(), .catch(), .finally(), .cancel(), and .promise() methods on every request call object
  • Automatic rejection on non-2xx status codes via simple (default true), with StatusCodeError and TransformError error types from request-promise-core
  • A transform option to reshape the response body before the promise resolves, with transform2xxOnly to scope that transform to successful responses only
  • Cookie jar support via rp.jar() for sharing cookies across multiple requests

Common Use Cases

  • Maintaining a pre-2018 Node.js codebase - teams keeping an existing app running without a full HTTP-client migration in scope
  • Incremental migration off request - using request-promise as a stepping stone while porting call sites to axios, got, or fetch one at a time
  • Legacy scraping/crawling scripts - older tooling built around request’s transform option to pipe HTML straight into a parser like Cheerio
  • Reproducing legacy bug reports - debugging or patching an older service where the dependency tree still pins request/request-promise

Under The Hood

Architecture The entire public module is lib/rp.js, a ~45-line file that gets a fresh, isolated copy of Bluebird (getNewLibraryCopy()), loads an unaltered copy of request via stealthy-require (so consumers who also require('request') directly aren’t affected by the promise patching), and hands both to request-promise-core’s configure(...) call, which does the actual work of attaching .then/.catch/.finally/.cancel/.promise to request’s call objects. Error types (StatusCodeError, TransformError) are re-exported from errors.js, itself a one-line re-export of request-promise-core/errors. There’s effectively no independent architecture here — request-promise is a thin, single-purpose configuration shim over a shared core package that also powers its siblings request-promise-native and request-promise-any.

Tech Stack Runtime dependencies are request-promise-core (the shared configure/error logic), bluebird (^3.5) for the promise implementation, stealthy-require (^1.1.1) for cache-isolated re-requiring, and tough-cookie (^2.3.3) for the cookie-jar API; request (^2.34) is a peer dependency, left to the consumer to install. The dev/build stack is gulp-based — gulp-mocha for tests, gulp-istanbul/gulp-coveralls for coverage, gulp-eslint for linting — run through Travis CI against Node 0.10 through 10 plus io.js, a version matrix that dates the project squarely to the mid-2010s.

Code Quality Tests exist and are real: test/spec/request-test.js spins up a local fixture HTTP server (test/fixtures/server.js) and exercises .then(), .catch(), .finally(), .promise(), cookie jars, and error types against live requests rather than mocks, run via Mocha with Istanbul coverage reporting to Coveralls in CI. ESLint is configured with ecmaVersion: 5, meaning the codebase is deliberately held to pre-ES6 syntax throughout — no arrow functions, no let/const, no classes — consistent with supporting the ancient Node versions in the Travis matrix. No TypeScript or type annotations anywhere. Naming and error handling are consistent and explicit (dedicated error classes rather than generic Error), but the project has had no meaningful commits since early 2024 and none of substance since the 2020 deprecation notice was added.

API Design The entire ergonomic pitch is that it requires almost no new API to learn: existing request(options, callback) call sites become rp(options).then(...) with the same options object, so migration from raw request was originally near-zero-boilerplate. That same design is now its ceiling — it’s a promise decorator bolted onto a callback-era library’s shape rather than a client designed promise-first, which is exactly the gap axios, got, and native fetch closed. There’s no meaningful documentation site beyond the README, though the README itself is thorough with runnable examples for every option.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search