HTTP client for JavaScript: which one to choose?

javascript http client
Andrés Cidel

Developers often choose an HTTP client when they consume APIs, for example as they build frameworks. Which HTTP clients should be considered by JavaScript developers?

Imagine you would be building your own framework, or building something light with lightweight libraries. Then, choosing your tools becomes a complicated thing if you try to cover all corner cases in terms of performance. But, probably there are other topics that you have to keep in mind and you haven’t even thought about. This article discusses how to choose a HTTP client library, while keeping in mind some important considerations.

Popular JavaScript HTTP clients

We have based our selection on a list of the most popular HTTP client libraries written in JavaScript. They were included in the list because they have more than 2,000 stars at Github. There are of course other, perhaps better, ways to measure the popularity of a package/library. But either way, there’s a relatively high probability you’re opting for one of the following clients.

HTTP client 1: got

got. The request parameters remains the same. To make this library work only the response of the request has to be changed. Example of usage:

const got = require('got');

(async () => {
  try {
    const response = await got('');
    //=>; '<!doctype html> ...'
  } catch (error) {
    //=>; 'Internal server error ...'

HTTP client 2: restler

var rest = require('./restler');

rest.get('').on('complete', function(result) {
  if (result instanceof Error) {
    console.log('Error:', result.message);
    this.retry(5000); // try again after 5 sec
  } else {

HTTP client 3: request

request. For request, if the client wants to configure the options of the request it has to send a plain object.

var request = require('request');
request('', function (error, response, body) {
  console.log('error:', error); // Print the error if one occurred
  console.log('statusCode:', response &&; response.statusCode); // Print the response status code if a response was received
  console.log('body:', body); // Print the HTML for the Google homepage.

HTTP client 4: reqwest

reqwest. Reqwest accepts the same parameters as request (the library mentioned above), but also can use the url as first parameter and the callback as second parameter. Example of usage:

reqwest('path/to/html', function (resp) {

    url: 'path/to/html'
  , method: 'post'
  , data: { foo: 'bar', baz: 100 }
  , success: function (resp) {

HTTP client 5: superagent

superagent This offers an interface with different methods, depending on the verb is the name of the method. Example of usage:

  .send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
  .set('X-API-Key', 'foobar')
  .set('accept', 'json')
  .end((err, res) => {
    // Calling the end function will send the request

Fetch API is out of the box

Fetch provides a way to perform HTTP requests with a lot of features and is supported by most of the modern browsers. It is widely used by the front-end community, especially React and React Native developers. Since it’s out of the box this should be enough reason to choose it.

But, what happens if we’re building an isomorphic framework? In this case, we shouldn’t be worried of the Web API side but in the node side. Node offers another interface to perform http calls different than fetch, it offers the http and https interfaces. From this perspective, we can either choose one of the isomorphic libraries listed above or just write an interface that accepts both, fetch from the web side and http/https from the node side.

Also, think about the following: take into account that a considerable amount of people that use your framework or library, want support of old browsers. Then, this problem gets a little bit more complicated.

Let’s analyze fetch in terms of support.

Browser support of fetch in current browsers

Not all the browsers provide support nowadays and that’s something important to keep in mind when choosing interfaces for web development. To get a better picture of the current fetching support status of modern browsers, we can take a look at this table.

From the table, we can conclude that using fetch won’t allow our applications to work in IE, Opera mini and UC Browser for Android. According to the percentage of users using those browsers (IE, 3.32%; Opera Mini, 2.84%; UC Browser 8.24%), we can reach about 85% of the total users globally. We have to keep in mind that this is just a wild estimation, but it provides a better understanding of the context.

Fetch in node

As mentioned, node provides an API to perform HTTP requests using both http and https modules. But not an interface like fetch in the browser. Fortunately, there’s a package that offers a lightweight module with the same set of functionalities, making it compatible with the fetch interface of the browser.


If your library needs to use an isomorphic HTTP client library, to perform the same operations in the Web side and node side, you can use something like axios or isomorphic-fetch, the problem comes when those libraries have several dependencies and that’s not good specially for web browser applications.

Finally, we can include a list of HTTP clients that work similar to fetch:

* NPMJS: Isomorphic fetch

* NPMJS: Node fetch

* Mozilla: Fetch API

* NPMJS: Fetch

We have three different approaches to make something simple and powerful:

–> Depend on a single isomorphic library. This makes it easy and reliable, but keep in mind it overloads the dependence tree

–> Rely on an standard (the current approach). This can be super flexible when using different libraries, instead of attaching it to a single one. The problem is that two different libraries could be used, then one could offer some features that the others couldn’t provide.

–> Develop these functionalities, making it isomorphic using the standard modules. This detaches your library of framework from any other library and makes it lightweight. The problem is that this requires more developing and tests (additional resources).