request-promise-core
request-promise-core is the internal adapter that adds Promise behavior to the old request HTTP client. It patches request's Request prototype, replaces each request callback with plumbing that resolves or rejects a chosen Promise implementation, and defines errors for transport failures, non-2xx status codes, and transform failures. It is not a standalone HTTP client, and its own README tells normal application developers to use a request-promise wrapper instead of configuring this package directly.
Do not install request-promise-core for new code. Keep it only when maintaining a custom wrapper around request 2.x, and plan migration at the HTTP-client boundary rather than building more prototype patches on top.
Use it if
- You maintain a legacy request-promise wrapper and need the same callback, transform, and error behavior as request-promise-core 1.1.4
- You must provide a custom Promise implementation while preserving request 2.x options and request object methods
- You are repairing an existing integration that imports configure/request2 and changing HTTP clients is outside the current scope
- You are writing a new application: the package is only plumbing for request, whose main repository is archived, so got, undici, axios, or native fetch has a healthier future
- You only want Promise-based HTTP calls: the README explicitly says to use one of the request-promise wrapper libraries unless you have very specific requirements
- You do not want global mutation: configure/request2 replaces request.Request.prototype.init and adds exposed methods to the same prototype
- You need TypeScript support: version 1.1.4 publishes no declaration file and declares no types entry, leaving direct users to write their own module declaration
- You want a self-contained dependency: request is a peer dependency and must be installed separately, while the runtime also pulls lodash
Setup reality
Installing this package alone is not enough. Version 1.1.4 declares request ^2.34 as a peer dependency, so a working legacy setup needs both npm install request and npm install request-promise-core. The README also recommends stealthy-require when application code or another dependency may load plain request, because configuration patches request.Request.prototype and a shared cached copy can unexpectedly gain then, catch, and promise methods. You must import configure/request2, pass the request function, provide a real Promise constructor, and list every Promise method to expose. The list cannot be empty and must contain then or configuration throws immediately. The patch is process-wide for that request module instance, so configure it once during startup rather than per call. Non-2xx responses reject by default because simple defaults to true; set simple: false if status codes are data. The resolved value is the body unless resolveWithFullResponse is true, while HEAD resolves to headers by default. There are no bundled TypeScript declarations, no ESM entry point, and no browser-specific build. The published code supports very old Node versions and CommonJS, but that compatibility also means the interface predates AbortController, native fetch, modern package exports, and current observability conventions. Treat it as containment work for a legacy request stack, not a foundation to add today.
Patterns
Install the core and its required HTTP clientinstall-peer-dependency
npm install request request-promise-corerequest is a peer dependency, not a bundled runtime dependency. Installing only request-promise-core leaves the adapter with nothing to patch.
Add native Promise methods to requestconfigure-native-promises
const request = require('request');
const configure = require('request-promise-core/configure/request2');
configure({
request,
PromiseImpl: Promise,
expose: ['then', 'catch', 'promise'],
});Configuration mutates request.Request.prototype. Run it once during process startup, and include then in expose or the configurator throws.
Load an isolated request copy before patchingisolate-patched-request
const stealthyRequire = require('stealthy-require');
const request = stealthyRequire(require.cache, () => require('request'));
const configure = require('request-promise-core/configure/request2');
configure({ request, PromiseImpl: Promise, expose: ['then', 'catch', 'promise'] });The README recommends isolation when other code expects an unmodified cached request export. stealthy-require must be installed separately.
Resolve a GET request to its bodyget-response-body
request({
method: 'GET',
uri: 'https://api.example.com/items',
json: true,
}).then((body) => {
console.log(body);
});The default resolved value is body, and non-2xx responses reject because simple defaults to true.
Send and receive JSONpost-json
const created = await request({
method: 'POST',
uri: 'https://api.example.com/items',
body: { name: 'paper clips' },
json: true,
});These are request 2.x options. request-promise-core only changes completion handling; serialization and transport still belong to request.
Resolve with status and headersread-full-response
const response = await request({
uri: 'https://api.example.com/items/42',
resolveWithFullResponse: true,
});
console.log(response.statusCode, response.headers, response.body);Without resolveWithFullResponse: true, successful calls resolve only to the body.
Treat non-2xx responses as normal resultsaccept-error-status
const response = await request({
uri: 'https://api.example.com/maybe-missing',
simple: false,
resolveWithFullResponse: true,
});
if (response.statusCode === 404) console.log('not found');simple: false disables StatusCodeError rejection. Network failures can still reject with RequestError.
Inspect a rejected HTTP statushandle-status-error
try {
await request({ uri: 'https://api.example.com/private', json: true });
} catch (error) {
if (error.name === 'StatusCodeError') {
console.error(error.statusCode, error.error);
} else {
throw error;
}
}StatusCodeError.error holds the response body, while response is the response object unless a transform changed the stored value.
Distinguish transport failureshandle-network-error
request({ uri: 'https://api.example.com/items', timeout: 5000 })
.catch((error) => {
if (error.name === 'RequestError') {
console.error('transport failed', error.cause);
return;
}
throw error;
});The original transport error is available as both cause and the legacy error property. Timeout behavior comes from request.
Transform a successful body before resolutiontransform-success-body
const names = await request({
uri: 'https://api.example.com/items',
json: true,
transform(body) {
return body.items.map((item) => item.name);
},
transform2xxOnly: true,
});A thrown or rejected transform becomes TransformError. transform2xxOnly avoids transforming an error response before StatusCodeError is created.
Get the underlying Promise instanceunwrap-promise
const pendingRequest = request('https://api.example.com/items');
const bodyPromise = pendingRequest.promise();
bodyPromise.then(console.log);promise() exists only if promise was included in expose. The request object remains abortable through request's own methods.
Issue a HEAD requestread-head-headers
const headers = await request({
method: 'HEAD',
uri: 'https://example.com/archive.zip',
});
console.log(headers['content-length']);HEAD has a built-in default transform: it resolves to response.headers, or to the full response when resolveWithFullResponse is true.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| got | npm | Node applications that want a maintained Promise-first HTTP client with retries, hooks, and modern cancellation |
| undici | npm | Node applications that want the HTTP client and fetch implementation maintained alongside Node.js |
| axios | npm | Teams that need one Promise-based client API across Node and browsers, especially for interceptors |