Fetch vs Axios in React: Which Should You Use?

Compare fetch and Axios for React data fetching. See how JSON parsing, error handling, timeouts, and interceptors differ, then pick the right one.

6 min read

Choosing between fetch and axios in React comes down to how much request handling you want to write by hand. Fetch is a built-in browser function that returns a promise you parse yourself. Axios is an installable promise-based HTTP client that parses JSON automatically and adds timeouts, interceptors, and progress events.

The core difference in one table

The main difference is ownership. Fetch ships with the browser and does the minimum: it returns a Response and leaves parsing, error handling, and timeouts to you.

Axios wraps that work in a package with sensible defaults. Axios 1.x is the current major version.

FeaturefetchAxios
InstallationBuilt into the browsernpm install axios
JSON parsingCall response.json() yourselfresponse.data is parsed automatically
Error handlingRejects only on network failureRejects on non-2xx statuses too
TimeoutsNone built intimeout option in milliseconds
InterceptorsNoneRequest and response interceptors
CancellationAbortController signalAbortController signal
Upload progressManual with streamsonUploadProgress callback

The two most noticeable differences are JSON parsing and error behavior. Axios gives you response.data ready to render and rejects on HTTP errors by default, while fetch makes you read and check both yourself. This is why a one-off request rarely justifies adding Axios, while an app with many endpoints often does.

Make the same GET request in both

A request that loads one user looks similar in both libraries. The fetch version below checks the status, parses JSON, and catches failures explicitly.

App.jsxApp.jsx
import { useEffect, useState } from "react";
 
useEffect(() => {
  fetch("/api/user/1")
    .then((res) => {
      if (!res.ok) throw new Error("Request failed");
      return res.json();
    })
    .then((data) => setUser(data))
    .catch(() => setError("Could not load user"));
}, []);

With fetch you own the happy path and the failure path. The Axios version below does the same job with less ceremony, after running npm install axios and importing the default export.

App.jsxApp.jsx
import axios from "axios";
 
useEffect(() => {
  axios
    .get("/api/user/1")
    .then((response) => setUser(response.data))
    .catch(() => setError("Could not load user"));
}, []);

The get call resolves directly to a response object, and response.data is already the parsed JSON. A failed status rejects the promise on its own, so one catch block handles both network and HTTP errors. That difference alone removes a check from every request you write.

What Axios adds out of the box

The extras matter once requests grow beyond a single GET. Three features each need custom code with fetch but come free with Axios.

  • Timeouts. Passing a timeout option aborts slow requests. With fetch you combine AbortController with a timer.
  • Interceptors. You can attach an auth header or refresh a token in one place instead of repeating it in every request.
  • Progress. The onUploadProgress and onDownloadProgress callbacks drive file transfer bars.

None of these are impossible with fetch. They are simply already written in Axios, which is why teams reach for it when requests multiply. These features are available in Axios 1.x, which keeps the same API in browsers and Node.js.

The basic pattern behind both libraries is the same and is explained in how to fetch API data in React.

Which should you use?

Choose fetch when the app is small, the endpoints are few, and you want zero dependencies. Choose Axios when you find yourself writing the same parsing, error, timeout, and header code in several places. Start with fetch and introduce Axios when that boilerplate shows up in three or more requests.

A third option matters here too. A data library such as TanStack Query adds caching, retries, and request deduplication on top of either client, so setting up TanStack Query in React can matter more than the fetch versus Axios choice. Both libraries also support cancellation through the same signal, which is covered in how to cancel fetch requests in React with AbortController.

Rune AI

Rune AI

Key Insights

  • fetch is built in; Axios is a package you install.
  • fetch returns raw JSON; Axios gives you response.data parsed.
  • fetch rejects only on network errors; Axios rejects non-2xx statuses too.
  • Axios adds timeouts, interceptors, and progress callbacks.
  • Start with fetch, move to Axios when you repeat the same request boilerplate.
RunePowered by Rune AI

Frequently Asked Questions

Is fetch enough for most React apps?

Yes for small apps with a few endpoints. You write a little more code for parsing, error checks, and timeouts, but there is no dependency to install.

Does Axios work in Node.js too?

Yes. Axios uses the browser XHR or fetch adapter in the browser and the http module in Node.js, so the same API works in both environments.

Is fetch built into every browser?

Yes. fetch is a browser global in all modern browsers and is also available in Web Workers and modern Node.js.

Conclusion

Fetch is the zero-dependency baseline and needs manual JSON parsing and error checks. Axios adds parsed data, automatic error rejection, timeouts, interceptors, and progress events, which pay off as request handling grows.