got vs axios vs isomorphic-fetch vs node-fetch
HTTP Client Strategies for Node.js and Frontend Architectures
gotaxiosisomorphic-fetchnode-fetchSimilar Packages:

HTTP Client Strategies for Node.js and Frontend Architectures

axios, got, isomorphic-fetch, and node-fetch are all tools for making HTTP requests, but they target different environments and development needs. axios is a promise-based HTTP client that works in both the browser and Node.js, known for its automatic JSON transformation and interceptors. got is a human-friendly HTTP client specifically for Node.js, offering advanced features like pagination and robust retry logic. isomorphic-fetch is a polyfill that enables the native fetch API in older environments, while node-fetch brings the fetch API specifically to Node.js environments prior to native support. Choosing between them depends on whether you need isomorphic code, Node-specific power features, or alignment with web standards.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
got31,278,18414,876304 kB12 months agoMIT
axios0108,5892.42 MB3477 days agoMIT
isomorphic-fetch06,927-575 years agoMIT
node-fetch08,858107 kB2333 years agoMIT

Axios vs Got vs Fetch Polyfills: Architecture & Runtime Compared

When architecting data layers for modern web applications, the choice of HTTP client impacts everything from bundle size to error handling strategies. axios, got, isomorphic-fetch, and node-fetch all solve the same fundamental problem β€” making HTTP requests β€” but they approach it from different angles. Let's compare how they handle real-world engineering scenarios.

🌍 Runtime Environment: Isomorphic vs Node-Only

axios is truly isomorphic.

  • It uses XMLHttpRequest in the browser and the native http module in Node.js.
  • You can share the same request logic between client and server without changes.
// axios: Works in Browser and Node
import axios from 'axios';
const res = await axios.get('/api/data');

got is strictly for Node.js.

  • It relies on Node-specific APIs like http and tls.
  • Importing it in a browser bundle will cause build errors or runtime crashes.
// got: Node.js Only
import got from 'got';
const res = await got.get('https://api.example.com/data');

isomorphic-fetch polyfills the global environment.

  • It injects fetch into the global scope for both Node and older browsers.
  • This can cause conflicts if other libraries also try to polyfill fetch.
// isomorphic-fetch: Global Polyfill
import 'isomorphic-fetch';
const res = await fetch('/api/data'); // Uses injected global

node-fetch is for Node.js environments.

  • It implements the fetch standard specifically for server-side JavaScript.
  • In modern Node (v18+), native fetch makes this package less critical.
// node-fetch: Node.js Implementation
import fetch from 'node-fetch';
const res = await fetch('https://api.example.com/data');

πŸ“ Request Syntax & Response Handling

axios wraps the response in an object and parses JSON automatically.

  • You access data via response.data.
  • No need to call .json() manually, which reduces boilerplate.
// axios: Auto-parsed JSON
const response = await axios.get('/api/user');
console.log(response.data); // Direct access to parsed body

got also simplifies response handling but returns a plain object.

  • It automatically parses JSON if the Content-Type header matches.
  • Access the body directly via response.body.
// got: Auto-parsed JSON
const response = await got.get('https://api.example.com/user');
console.log(response.body); // Direct access to parsed body

isomorphic-fetch follows the strict Fetch API standard.

  • Responses are not parsed automatically.
  • You must explicitly call .json() to read the payload.
// isomorphic-fetch: Manual JSON parsing
const response = await fetch('/api/user');
const data = await response.json(); // Explicit parsing required

node-fetch mirrors the standard Fetch API behavior.

  • Like isomorphic-fetch, it requires manual parsing.
  • This aligns with browser fetch but adds extra lines of code.
// node-fetch: Manual JSON parsing
const response = await fetch('https://api.example.com/user');
const data = await response.json(); // Explicit parsing required

⚠️ Error Handling Strategies

axios throws an error for any HTTP status outside 2xx.

  • You catch network errors and HTTP errors in the same catch block.
  • The error object contains the response, request, and status code.
// axios: Throws on 4xx/5xx
try {
  await axios.get('/api/protected');
} catch (error) {
  if (error.response) console.log(error.response.status);
}

got provides detailed error classes for different failure types.

  • It distinguishes between RequestError, HTTPError, and TimeoutError.
  • This granularity helps in writing precise retry logic.
// got: Detailed Error Classes
try {
  await got.get('https://api.example.com/protected');
} catch (error) {
  if (error instanceof got.HTTPError) console.log(error.response.statusCode);
}

isomorphic-fetch does not throw on HTTP errors (4xx/5xx).

  • It only rejects the promise on network failures (e.g., DNS down).
  • You must manually check response.ok to handle HTTP errors.
// isomorphic-fetch: Manual Error Check
const response = await fetch('/api/protected');
if (!response.ok) {
  throw new Error(`HTTP error! status: ${response.status}`);
}

node-fetch behaves identically to the standard Fetch API.

  • It does not reject promises for HTTP error statuses.
  • Developers must implement manual status checks to avoid silent failures.
// node-fetch: Manual Error Check
const response = await fetch('https://api.example.com/protected');
if (!response.ok) {
  throw new Error(`HTTP error! status: ${response.status}`);
}

πŸ› οΈ Advanced Features: Interceptors vs Hooks

axios uses interceptors to modify requests or responses globally.

  • Ideal for attaching auth tokens or logging every request.
  • You can register multiple interceptors that run in sequence.
// axios: Request Interceptors
axios.interceptors.request.use(config => {
  config.headers.Authorization = 'Bearer token';
  return config;
});

got uses hooks to achieve similar goals with more control.

  • Hooks can be defined per-request or globally via an extended instance.
  • They support async operations before redirection or finalization.
// got: Hooks
const api = got.extend({
  hooks: {
    beforeRequest: [
      options => { options.headers.authorization = 'Bearer token'; }
    ]
  }
});

isomorphic-fetch has no built-in interception mechanism.

  • To modify headers globally, you must wrap fetch in a custom function.
  • This adds maintenance overhead compared to built-in interceptor systems.
// isomorphic-fetch: Custom Wrapper
const originalFetch = fetch;
const fetchWithAuth = (url, opts = {}) => {
  opts.headers = { ...opts.headers, Authorization: 'Bearer token' };
  return originalFetch(url, opts);
};

node-fetch also lacks native interceptors.

  • Like isomorphic-fetch, you need to create a wrapper function for global logic.
  • This is a common pattern when using the standard Fetch API without extra libraries.
// node-fetch: Custom Wrapper
const originalFetch = fetch;
const fetchWithAuth = (url, opts = {}) => {
  opts.headers = { ...opts.headers, Authorization: 'Bearer token' };
  return originalFetch(url, opts);
};

πŸ“… Maintenance & Future Proofing

axios remains actively maintained with a large community.

  • It adapts to new environments but retains its legacy API surface.
  • A safe bet for long-term projects requiring stability.

got is actively developed for the Node ecosystem.

  • It embraces modern JavaScript features and ESM.
  • Best choice for server-side tools that need reliability.

isomorphic-fetch is considered legacy in modern stacks.

  • Native fetch is now available in all major browsers and Node 18+.
  • New projects should avoid this dependency unless supporting very old clients.

node-fetch is stable but less critical with Node 18+.

  • Version 3 requires ESM, which may break older CommonJS projects.
  • Use native fetch in new Node projects where possible.

πŸ“Š Summary: Key Differences

Featureaxiosgotisomorphic-fetchnode-fetch
Environment🌐 Browser & NodeπŸ–₯️ Node Only🌐 Browser & Node (Polyfill)πŸ–₯️ Node Only
JSON Parsingβœ… Automaticβœ… Automatic❌ Manual (.json())❌ Manual (.json())
Error Handling⚠️ Throws on 4xx/5xx⚠️ Throws on 4xx/5xxβœ… OK Status Checkβœ… OK Status Check
InterceptorsπŸ› οΈ Built-inπŸ› οΈ Hooks❌ Custom Wrapper❌ Custom Wrapper
Status🟒 Active🟒 Active🟑 Legacy🟒 Stable

πŸ’‘ The Big Picture

axios is the pragmatic choice for full-stack teams 🧰. It reduces boilerplate with auto-parsing and interceptors, making it ideal for dashboards, admin panels, and apps where client/server code sharing matters.

got is the power user's tool for Node.js πŸ”§. If you are building backend services, CLI tools, or scripts, its advanced retry logic and error details save hours of debugging.

isomorphic-fetch and node-fetch are for standard-compliance purists πŸ“œ. They are useful if you want to match browser fetch behavior exactly, but be aware that isomorphic-fetch is fading in favor of native implementations.

Final Thought: For most modern frontend architectures, native fetch (with a small wrapper for error handling) or axios (for interceptors) are the top contenders. Reserve got for dedicated Node.js services where its specific strengths shine.

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

  • got:

    Choose got if you are building a backend or CLI tool strictly in Node.js. It offers superior developer experience for server-side tasks, including built-in pagination, advanced retry strategies, and detailed error reporting that axios or fetch do not provide out of the box.

  • axios:

    Choose axios if you need a single library that works identically in both the browser and Node.js without configuration. It is ideal for projects that rely heavily on interceptors for authentication or logging, and for teams that prefer automatic JSON parsing over manual response handling.

  • isomorphic-fetch:

    Choose isomorphic-fetch only if you must support legacy environments that lack native fetch and you want to write standard fetch syntax. However, for new projects, prefer native fetch or axios, as this package is considered legacy and adds unnecessary global polyfills.

  • node-fetch:

    Choose node-fetch if you are on Node.js versions prior to 18 and want to use the standard fetch API syntax without the extra features of axios. Note that version 3 is ESM-only, so ensure your project supports ES modules, or stick to version 2 for CommonJS.

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 cancelation:heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark::heavy_check_mark:
RFC compliant 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.
ΒΉ Requires Node.js 15.10.0 or above.
: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

These amazing companies are using Got


Segment is a happy user of Got! Got powers the main backend API that our app talks to. It's used by our in-house RPC client that we use to communicate with all microservices.

β€” Vadim Demedes

Antora, a static site generator for creating documentation sites, uses Got to download the UI bundle. In Antora, the UI bundle (aka theme) is maintained as a separate project. That project exports the UI as a zip file we call the UI bundle. The main site generator downloads that UI from a URL using Got and streams it to vinyl-zip to extract the files. Those files go on to be used to create the HTML pages and supporting assets.

β€” Dan Allen

GetVoIP is happily using Got in production. One of the unique capabilities of Got is the ability to handle Unix sockets which enables us to build a full control interfaces for our docker stack.

β€” Daniel Kalen

We're using Got inside of Exoframe to handle all the communication between CLI and server. Exoframe is a self-hosted tool that allows simple one-command deployments using Docker.

β€” Tim Ermilov

Karaoke Mugen uses Got to fetch content updates from its online server.

β€” Axel Terizaki

Renovate uses Got, gh-got and gl-got to send millions of queries per day to GitHub, GitLab, npmjs, PyPi, Packagist, Docker Hub, Terraform, CircleCI, and more.

β€” Rhys Arkins

Resistbot uses Got to communicate from the API frontend where all correspondence ingresses to the officials lookup database in back.

β€” Chris Erickson

Natural Cycles is using Got to communicate with all kinds of 3rd-party REST APIs (over 9000!).

β€” Kirill Groshkov

Microlink is a cloud browser as an API service that uses Got widely as the main HTTP client, serving ~22M requests a month, every time a network call needs to be performed.

β€” Kiko Beats

We’re using Got at Radity. Thanks for such an amazing work!

β€” Mirzayev Farid