got vs request vs axios vs node-fetch
HTTP Client Libraries for Node.js and Frontend
gotrequestaxiosnode-fetchSimilar Packages:

HTTP Client Libraries for Node.js and Frontend

axios, got, node-fetch, and request are tools for making HTTP requests in JavaScript. axios works in both browsers and Node.js. got and node-fetch are built for Node.js environments. request is an older library that is no longer maintained. These tools help developers connect their applications to APIs, download files, and send data to servers.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
got42,182,36614,953488 kB03 days agoMIT
request12,479,40925,489-1447 years agoApache-2.0
axios0109,3011.98 MB992 months agoMIT
node-fetch08,848107 kB2493 years agoMIT

Axios vs Got vs Node-Fetch vs Request: HTTP Clients Compared

Making HTTP requests is a daily task for JavaScript developers. Whether you are fetching data for a website or calling a microservice on the server, you need a reliable tool. axios, got, node-fetch, and request have all been popular choices, but they serve different needs today. Let's compare how they handle real-world tasks.

⚠️ Maintenance Status: Safe vs Deprecated

Before writing any code, you must know which tools are safe to use. This is the most critical difference in this group.

request is officially deprecated.

  • The maintainers stopped working on it in 2020.
  • It will not receive security fixes or bug updates.
  • Using it puts your project at risk.
// request: DEPRECATED - Do not use in new projects
const request = require('request');
// This library is no longer maintained

axios, got, and node-fetch are actively maintained.

  • They receive regular updates for security and features.
  • They support modern JavaScript standards like Promises and async/await.
  • Safe for production use today.
// axios, got, node-fetch: Actively maintained
import axios from 'axios';
import got from 'got';
import fetch from 'node-fetch';
// All safe for current development

🌍 Environment Support: Browser vs Node.js

Where your code runs matters. Some tools work everywhere, while others are built specifically for the server.

axios works in both browsers and Node.js.

  • You can use the same code on the frontend and backend.
  • Great for universal apps or shared utility libraries.
// axios: Works everywhere
import axios from 'axios';
// Runs in Chrome, Firefox, Node.js, etc.
const response = await axios.get('/api/data');

got is for Node.js only.

  • It uses Node-specific features like streams.
  • It will not work if you try to bundle it for the browser.
// got: Node.js only
import got from 'got';
// Will fail if bundled for browser
const response = await got.get('/api/data');

node-fetch is for Node.js only.

  • It brings the browser fetch API to the server.
  • Modern Node.js (v18+) now has fetch built-in, reducing the need for this package.
// node-fetch: Node.js only
import fetch from 'node-fetch';
// Modern Node has global fetch built-in
const response = await fetch('/api/data');

request was for Node.js only.

  • It was never designed to run in the browser.
  • Another reason to avoid it for modern full-stack projects.
// request: Node.js only (Legacy)
const request = require('request');
// Cannot be used in browser environments

πŸ“₯ Making a Basic GET Request

How much code do you need to fetch simple data? Syntax clarity impacts daily development speed.

axios returns the data directly in a data property.

  • It automatically parses JSON for you.
  • The response object wraps the actual content.
// axios: Auto JSON parse
const response = await axios.get('/api/users');
console.log(response.data); // The actual JSON content

got also returns the body directly by default.

  • It behaves similarly to axios for simple cases.
  • Very concise for standard API calls.
// got: Auto JSON parse
const response = await got.get('/api/users');
console.log(response.body); // The actual JSON content

node-fetch returns a Response object.

  • You must manually call .json() to parse the data.
  • This matches the browser standard exactly.
// node-fetch: Manual JSON parse
const response = await fetch('/api/users');
const data = await response.json(); // Must parse manually
console.log(data);

request uses callbacks instead of Promises.

  • This leads to nested code or requires extra wrappers.
  • Much harder to read than modern async/await syntax.
// request: Callback based (Legacy)
request('/api/users', (error, response, body) => {
  const data = JSON.parse(body); // Manual parse
  console.log(data);
});

🚨 Error Handling: Automatic vs Manual

What happens when the server returns a 404 or 500 error? Some tools throw errors for you, while others make you check manually.

axios throws an error for bad status codes.

  • You can wrap calls in try/catch blocks.
  • You do not need to check status codes manually.
// axios: Throws on 4xx/5xx
try {
  await axios.get('/api/broken');
} catch (error) {
  console.log('Request failed automatically');
}

got also throws an error for bad status codes.

  • Similar behavior to axios.
  • Makes error handling consistent and predictable.
// got: Throws on 4xx/5xx
try {
  await got.get('/api/broken');
} catch (error) {
  console.log('Request failed automatically');
}

node-fetch does NOT throw on bad status codes.

  • You must check response.ok yourself.
  • Easy to forget, which can hide bugs in production.
// node-fetch: Does NOT throw on HTTP error
const response = await fetch('/api/broken');
if (!response.ok) {
  throw new Error('Request failed'); // Must check manually
}

request passes errors to the callback.

  • You have to check the error argument first.
  • Mixing network errors with HTTP errors can be confusing.
// request: Callback error handling
request('/api/broken', (error, response, body) => {
  if (error) {
    console.log('Network error'); // Check error arg
  }
});

πŸ”„ Advanced Features: Interceptors and Hooks

Large applications often need to modify requests or responses globally. This is useful for adding auth tokens or logging.

axios has built-in interceptors.

  • You can run code before every request or after every response.
  • Very popular for adding authentication headers automatically.
// axios: Interceptors
axios.interceptors.request.use(config => {
  config.headers.Authorization = 'Bearer token';
  return config;
});

got uses hooks for similar functionality.

  • Hooks allow you to modify options or handle responses.
  • Powerful and flexible for backend services.
// got: Hooks
const client = got.extend({
  hooks: {
    beforeRequest: [
      options => {
        options.headers.authorization = 'Bearer token';
      }
    ]
  }
});

node-fetch has no built-in interceptor system.

  • You must create your own wrapper function.
  • Requires extra code to achieve the same result.
// node-fetch: Manual wrapper
async function fetchWithAuth(url) {
  return fetch(url, {
    headers: { Authorization: 'Bearer token' }
  });
}

request used plugins and jars.

  • This approach is outdated compared to modern interceptors.
  • Another reason why it feels old compared to new tools.
// request: Plugins (Legacy)
// Required external libraries for complex logic
// No native interceptor concept like axios

πŸ“Š Summary: Key Differences

Featureaxiosgotnode-fetchrequest
Statusβœ… Activeβœ… Activeβœ… Active❌ Deprecated
Environment🌐 Browser + NodeπŸ–₯️ Node OnlyπŸ–₯️ Node OnlyπŸ–₯️ Node Only
Promise Basedβœ… Yesβœ… Yesβœ… Yes❌ Callbacks
Auto JSONβœ… Yesβœ… Yes❌ Manual❌ Manual
Error Handlingβœ… Throwsβœ… Throws❌ Check .ok⚠️ Callback
Interceptorsβœ… Built-inβœ… Hooks❌ Manual❌ Plugins

πŸ’‘ The Big Picture

axios is the safe bet for full-stack teams 🧰. It works everywhere and handles common tasks automatically. Choose it if you want to write less code and share logic between frontend and backend.

got is the power tool for Node.js backends πŸ”§. It offers the best performance and features for server-side scripts. Choose it if you are building microservices or CLI tools.

node-fetch is the lightweight standard πŸͺΆ. It mimics the browser API perfectly. Choose it if you want minimal dependencies and your team already knows the fetch API.

request is history πŸ›‘. It is deprecated and should not be used. If you see it in an old project, plan to replace it soon.

Final Thought: For most new projects, start with axios for versatility or got for pure Node.js power. Avoid request entirely, and consider using native fetch if you are on Node.js 18 or higher.

How to Choose: got vs request vs axios vs node-fetch

  • got:

    Choose got if you are building backend services in Node.js. It offers the best developer experience for server-side code with strong stream support. It is not suitable for browser applications.

  • request:

    Do not choose this package. It is deprecated and no longer receives security updates. You should migrate existing projects to axios, got, or native fetch.

  • axios:

    Choose axios if you need one library for both browser and server code. It handles JSON automatically and has built-in request interceptors. Good for teams wanting consistency across platforms without switching tools.

  • node-fetch:

    Choose node-fetch if you want a lightweight API that matches the browser fetch standard. It is ideal for simple Node.js scripts where you do not need advanced features like automatic JSON parsing.

README for got



Got




Sindre's open source work is supported by the community.
Special thanks to:



Fame Helsinki Fame Helsinki



Depot logo
Fast remote container builds and GitHub Actions runners.











Human-friendly and powerful HTTP request library for Node.js

Downloads Install size

See how Got compares to other HTTP libraries


You probably want Ky instead, by the same people. It's smaller, works in the browser too, and is more stable since it's built on Fetch. Or fetch-extras for simple needs.


Support questions should be asked here.

Install

npm install got

Warning: This package is native ESM and no longer provides a CommonJS export. If your project uses CommonJS, you will have to convert to ESM. Please don't open issues for questions regarding CommonJS / ESM.

Got v11 is no longer maintained and we will not accept any backport requests.

Take a peek

A quick start guide is available.

JSON mode

Got has a dedicated option for handling JSON payload.
Furthermore, the promise exposes a .json<T>() function that returns Promise<T>.

import got from 'got';

const {data} = await got.post('https://httpbin.org/anything', {
	json: {
		hello: 'world'
	}
}).json();

console.log(data);
//=> {"hello": "world"}

For advanced JSON usage, check out the parseJson and stringifyJson options.

For more useful tips like this, visit the Tips page.

Highlights

Documentation

By default, Got will retry on failure. To disable this option, set options.retry.limit to 0.

Main API

Timeouts and retries

Advanced creation

Cache, Proxy and UNIX sockets

Integration


Migration guides

Got plugins

  • got4aws - Got convenience wrapper to interact with AWS v4 signed APIs
  • gh-got - Got convenience wrapper to interact with the GitHub API
  • gl-got - Got convenience wrapper to interact with the GitLab API
  • gotql - Got convenience wrapper to interact with GraphQL using JSON-parsed queries instead of strings
  • got-fetch - Got with a fetch interface
  • got-scraping - Got wrapper specifically designed for web scraping purposes
  • got-ssrf - Got wrapper to protect server-side requests against SSRF attacks

Comparison

gotnode-fetchkyaxiossuperagent
HTTP/2 support:heavy_check_mark::x::heavy_check_mark::x::heavy_check_mark:**
Browser support:x::heavy_check_mark:*:heavy_check_mark::heavy_check_mark::heavy_check_mark:
Promise API:heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark:
Stream API:heavy_check_mark:Node.js only:x::x::heavy_check_mark:
Pagination API:heavy_check_mark::x::x::x::x:
Request aborting:heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark:
RFC 7234 caching:heavy_check_mark::x::x::x::x:
Cookies (out-of-the-box):heavy_check_mark::x::x::x::x:
Follows redirects:heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark:
Retries on failure:heavy_check_mark::x::heavy_check_mark::x::heavy_check_mark:
Progress events:heavy_check_mark::x::heavy_check_mark:Browser only:heavy_check_mark:
Handles gzip/deflate:heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark:
Advanced timeouts:heavy_check_mark::x::x::x::x:
Timings:heavy_check_mark::x::x::x::x:
Errors with metadata:heavy_check_mark::x::heavy_check_mark::heavy_check_mark::x:
JSON mode:heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark:
Custom defaults:heavy_check_mark::x::heavy_check_mark::heavy_check_mark::x:
Composable:heavy_check_mark::x::x::x::heavy_check_mark:
Hooks:heavy_check_mark::x::heavy_check_mark::heavy_check_mark::x:
Issues open
Issues closed
Downloads
CoverageTBD
Build
Bugs
Dependents
Install size
GitHub stars
TypeScript support
Last commit

* It's almost API compatible with the browser fetch API.
** Need to switch the protocol manually. Doesn't accept PUSH streams and doesn't reuse HTTP/2 sessions.
:sparkle: Almost-stable feature, but the API may change. Don't hesitate to try it out!
:grey_question: Feature in early stage of development. Very experimental.

Click here to see the install size of the Got dependencies.

Maintainers

Sindre SorhusSzymon Marczak
Sindre SorhusSzymon Marczak