Migrating away from request - Complete Guide

The request npm package has been deprecated since February 2020 and receives no security patches. With 15M+ weekly downloads it is still in millions of production applications. This guide covers migrating to axios, got, or native fetch.

request is deprecated

request has been officially deprecated since February 11, 2020. No security patches, no bug fixes, no updates. Any CVE discovered in request will never be fixed. The maintainers explicitly recommend migration.

Choose your replacement

Most popular

axios

The most widely-used Node.js HTTP client. Works in Node.js and the browser. Promise-based, supports interceptors, automatic JSON parsing.

npm install axios

Easiest migration from request

got

Designed as a modern replacement for request. Supports retries, pagination, HTTP/2. ESM-only in v12+.

npm install got

No dependency (Node 18+)

Native fetch

Built into Node.js 18+. No install needed. Covers basic GET and POST with no dependencies.

Built-in - no install

Lightweight

node-fetch

Polyfills the browser fetch API for Node.js. ESM-only in v3, CJS in v2.

npm install node-fetch

Option A - Migrate to axios (recommended)

Install

npm install axios
npm uninstall request request-promise

GET requests

request
const request = require('request')

// Callback style
request('https://api.example.com/data', (err, res, body) => {
  if (err) throw err
  const data = JSON.parse(body)
  console.log(data)
})

// With request-promise
const rp = require('request-promise')
const data = await rp.get({
  uri: 'https://api.example.com/data',
  json: true
})
axios
const axios = require('axios')
// or: import axios from 'axios'

// Automatic JSON parsing
const { data } = await axios.get('https://api.example.com/data')
console.log(data)

// With options
const { data } = await axios.get('https://api.example.com/data', {
  params: { page: 1 },
  headers: { Authorization: 'Bearer token' }
})

POST requests

request
request.post({
  url: 'https://api.example.com/users',
  json: true,
  body: { name: 'Alice', email: 'alice@example.com' }
}, (err, res, body) => {
  console.log(body)
})
axios
const { data } = await axios.post('https://api.example.com/users', {
  name: 'Alice',
  email: 'alice@example.com'
})
console.log(data)

Error handling

request
request('https://api.example.com', (err, res, body) => {
  if (err) {
    console.error('Network error:', err)
    return
  }
  if (res.statusCode !== 200) {
    console.error('HTTP error:', res.statusCode)
    return
  }
  console.log(JSON.parse(body))
})
axios
try {
  const { data } = await axios.get('https://api.example.com')
  console.log(data)
} catch (err) {
  if (err.response) {
    // non-200 response
    console.error('HTTP error:', err.response.status)
  } else {
    // network failure
    console.error('Network error:', err.message)
  }
}

Headers and auth

request
request({
  url: 'https://api.example.com/data',
  headers: {
    'Authorization': 'Bearer mytoken',
    'X-Custom-Header': 'value'
  },
  auth: { user: 'username', pass: 'password' }
}, callback)
axios
// Per-request headers
await axios.get('https://api.example.com/data', {
  headers: {
    'Authorization': 'Bearer mytoken',
    'X-Custom-Header': 'value'
  },
  auth: { username: 'username', password: 'password' }
})

// Global defaults
axios.defaults.headers.common['Authorization'] = 'Bearer mytoken'

Option B - Migrate to got

got is ESM-only from v12. If you are on CommonJS (require()), use got v11 or switch to axios.

npm install got@11   # CommonJS compatible
npm install got      # ESM only (v12+)
request
const request = require('request')

request.get({
  url: 'https://api.example.com/data',
  json: true
}, (err, res, body) => {
  console.log(body)
})
got v11
const got = require('got')

const body = await got('https://api.example.com/data').json()
console.log(body)

// With options
const body = await got('https://api.example.com/data', {
  searchParams: { page: 1 },
  headers: { Authorization: 'Bearer token' }
}).json()

Option C - Native fetch (Node.js 18+)

No install required. Best for simple requests where you do not need retries or interceptors.

request
request('https://api.example.com/data', (err, res, body) => {
  const data = JSON.parse(body)
  console.log(data)
})
native fetch
// Built into Node.js 18+
const res = await fetch('https://api.example.com/data')
if (!res.ok) throw new Error('HTTP error: ' + res.status)
const data = await res.json()
console.log(data)

// POST
const res = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Alice' })
})
const data = await res.json()

Check your CVE exposure first

Paste your package.json into PackageFix to see which request-related CVEs you are currently exposed to.

Check your current dependencies for CVEs before migrating.

Scan with PackageFix →

Free · No signup · No CLI · Runs in your browser

Common questions

Is request still safe to use?
request has been deprecated since February 2020 - no security patches, no updates. Any new CVE will never be fixed. You should migrate.
Which replacement is easiest to migrate from request?
got has an API most similar to request and was designed as a modern replacement. axios is the most popular choice overall. For Node.js 18+, native fetch works for simple use cases.
Does request support async/await?
request uses callbacks natively. The request-promise wrapper is also deprecated. Modern alternatives support async/await natively.
Is axios safe to use in 2026?
axios 1.7.4 has no unpatched CVEs. It is actively maintained and the most widely used JavaScript HTTP client for both Node.js and browser environments.
Should I use native fetch instead of a library?
For Node.js 18+, the built-in fetch handles most HTTP use cases with zero dependencies. For retries, interceptors, or streaming, a library like got or axios is worth the dependency.

Related