Fetch or Axios - What Is Better for HTTP Requests?

by Anna Danilec

Intro to Fetch vs. Axios

One of the most essential parts of frontend development is communication with the backend by making HTTP requests. There are a few ways how we can make API calls in Javascript asynchronously.

A few years ago, most applications were sending HTTP requests using Ajax, which stands for Asynchronous Javascript and XML. But right now, developers mostly decide about selection between fetch() API and Axios.

In this article, I’d like to compare those two methods, go through basic overview and syntax. Besides that, I’ll compare the process of converting data to JSON format in both cases and error handling as well. I’m also going to talk about HTTP interception and download progress.

Let’s start!

Fetch overview and syntax

When we are building a Javascript project, we can use a window object, and it comes with many great methods that we can use in the project. One of those features is Fetch API, which provides an easy, global .fetch() method, which is a logic solution to fetch data from the API asynchronously.

Let’s take a look at the syntax of the .fetch() method.

  .then((res) => 
    // handle response
  .catch((error) => {
    // handle error

In the example above, you can see the syntax of a simple fetch GET request. In .fetch() method, we have one mandatory argument url. It returns a Promise, which can resolve with the Response object.

The second argument in .fetch() method are options, and it’s optional. If we won’t pass the options the request is always GET, and it downloads the content from the given URL.

Inside the options parameter, we can pass methods or headers, so if we would like to use the POST method or any other, we have to use this optional array.

As I mentioned before, the Promise returns the Response object, and because of that, we need to use another method to get the body of the response. There are a few different methods that we can use, depends on the format of the body that we need:

Let’s take a look at the code example with an optional parameter.

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  body: JSON.stringify(data)
  .then((response) => response.json())
  .catch((error) => console.log(error))

In the code example above, you can see the simple POST request with method, header, and body params. Then I use json() method to convert the response to JSON format.

Now, let’s take a closer look at the axios.

Axios overview and syntax

Axios is a Javascript library for making HTTP requests from Node.js or XMLHttpRequests or browser. As a modern library, it’s based on Promise API.

axios has some advantages that are like protection against XSRF or canceling requests.

To be able to use axios library, we have to install it and import it to our project. axios can be installed using CDN, npm, or bower. Now let’s take a look at the syntax of a simple GET method.

  .then(response => console.log(response));
  .catch((error) => console.log(error));

In the code above, you can see how I user axios to create a simple GET request using .get() method. If you’d like to use the POST method in the function, then it’s enough to use .post() method instead and pass the request data as a parameter.

When we are creating a config object we can define bunch of properties, the most common are:

As a response, axios returns a promise that will resolve with the response object or an error object. In the response object, there are the following values:

Right now, let’s take a look at the code example with the POST method with data.

  { name: 'John', age: 22},
  { options }

In the code above, you can see the post method, where we put the config object as a param, with URL, data, and additional options.

We can also define the config object as a variable and pass it to the axios like in the example below.

const config = {
  url: 'http://api.com',
  method: 'POST',
  header: {
    'Content-Type': 'application/json'
  data: {
    name: 'John',
    age: 22


Here, you can see that all the parameters, including URL, data, or method, are in the config object, so it may be easier to define everything in one place.


As I mentioned before, when we are using .fetch() method, we need to use some kind of method on the response data, and when we are sending the body with the request, we need to stringify the data.

In axios it’s done automatically, so we just pass data in the request or get data from the response. It’s automatically stringified, so no other operations are required.

Let’s see how we can get data from fetch() and from axios.

// fetch
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.log(error))

// axios
  .then((response) => console.log(response))
  .catch((error) => console.log(error))

In the example above, you can see that with axios we don’t have an additional line of code, where we have to convert data to JSON format, and we have this line in .fetch() example. In the case of a bigger project where you create a lot of calls, it’s more comfortable to use axios to avoid repeating the code.

Error handling

At this point, we also need to give points for axios as handling errors is pretty easy. If there will be a bad response like 404, the promise will be rejected and will return an error, so we need to catch an error, and we can check what kind of error it was, that’s it. Let’s see the code example.

  .then((response) => console.log(response))
  .catch((error) => {
    if (error.response) {
      // When response status code is out of 2xx range 
    } else if (error.request) {
      // When no response was recieved after request was made
    } else {
      // Error

In the code above, I’ve returned data when the response was good, but if the request failed in any way, I was able to check the type of error in .catch() part and return the proper message.

With the .fetch() method, it’s a little bit more complicated. Every time we get a response from the .fetch() method, we need to check if the status is a success because even if it’s not, we will get the response. In case of .fetch() promise won’t be resolved only when the request won’t be completed. Let’s see the code example.

  .then((response) => {
    if (!response.ok) {
      throw Error(response.statusText);
    return response.json()
  .then((data) => console.log(data))
  .catch((error) => console.log(error))

In this code, I’ve checked the status of the code in the promise object, and if the response had status ok, then I could process and use .json() method, but if not, I had to return error inside .then().

For easy and proper error handling, axios will be definitely a better solution for your project, but still, if you are building a small project with one or two requests, it’s fine to use .fetch(), but you need to remember to handle errors correctly.

Download progress

When we have to download a large amount of data, a way to follow the progress would be useful, especially when users have slow internet. Earlier, to implement progress indicators developers used XMLHttpRequest.onprogress callback. In .fetch() and axios, there are different ways to do it.

To track progress of download in .fetch() we can use one of the response.body properties, a ReadableStream object. It provides body data chunk by chunk, and it allows us to count how much data is consumed in time.

In axios, implementing a progress indicator is possible as well, and it’s even easier because there exists a ready module, which can be installed and implemented; it’s called Axios Progress Bar.

If you have a lot of large data to download and you want to track the progress in progress indicator, you can manage that easier and faster with axios but .fetch() gives the possibility as well, just it needs more code to be developed for the same result.

HTTP interception

HTTP interception can be important when we need to check or change our HTTP requests from the application to the server, or in the other way, for example, for authentication.

In the case of axios HTTP interception is one of the key features of this library, that’s why we don’t have to create additional code to use it. Let’s take a look at the code example to see how easy we can do it.

// request interceptor
axios.interceptors.request.use((config) => {
  console.log('Request sent');

// response interceptor
axios.interceptors.response.use((response) => {
  // do an operation on response
  return response

  .then((response) => console.log(response))
  .catch((error) => console.log(error))

In the code, you can see the request interception and response interception. In the first case, I created a console.log informing about sending requests, and in the response interception, we can do any action on response and then return it.

.fetch() doesn’t provide the HTTP interception by default, there’s a possibility to overwrite the .fetch() method and define what needs to happen during sending the request, but of course, it will take more code and can be more complicated than using axios functionality.


In this article, I compare two methods used for creating HTTP requests, starting for a simple overview, through syntax and some important features like download progress or error handling.

This comparison shows that Axios is a better solution in case of an application where there are a lot of HTTP requests which needs a good error handling or HTTP interceptions. In the case of small projects, with just a few simple API calls, Fetch can be a good solution as well.

It’s very important to pay attention to one more factor when choosing the best solution for your project. Axios is supported by most browsers and the Node.JS environment as well when Fetch is supported just by modern browsers and may have some issued with the older ones.

With this knowledge, I hope you are able to select the best solution for you, and you find this comparison helpful.

Thank you for reading,

Anna Danilec

If you liked it share and comment!