2025-01-08 Web Development

Comparing Axios and Fetch: Choosing the Right Tool for Your API Calls

By O. Wolfson

When working with APIs in JavaScript, two popular tools for making HTTP requests are the native fetch function and the third-party library axios. While both are capable of handling HTTP requests, each has unique features that suit different use cases. This article demonstrates their differences through examples using the JSONPlaceholder API.

Prerequisites

To follow along, ensure you have:

  • Node.js installed on your system.
  • A basic understanding of JavaScript and asynchronous programming.

We will use jsonplaceholder to fetch posts data.


Example 1: Fetching Data with fetch

Code Example

javascript
import fetch from "node-fetch";

const fetchPosts = async () => {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/posts");

    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    const data = await response.json();
    console.log("Posts fetched using fetch:", data);
  } catch (error) {
    console.error("Error fetching posts with fetch:", error);
  }
};

fetchPosts();

Key Features of fetch

  1. Built-In Functionality: fetch is native to JavaScript, requiring no external dependencies.
  2. Simple Syntax for Basic Calls: Works well for straightforward requests.
  3. Manual Error Handling: Developers must handle HTTP errors explicitly.
  4. JSON Parsing: Response data must be manually converted to JSON using response.json().

Pros of fetch

  • No additional dependency, which reduces project size.
  • Works directly in modern browsers and Node.js (via libraries like node-fetch).
  • Ideal for simple, lightweight requests.

Cons of fetch

  • Limited error handling—status codes like 404 or 500 do not throw errors automatically.
  • No timeout support without custom implementation.
  • Requires additional work for advanced use cases (e.g., request cancellation).

Example 2: Fetching Data with axios

Code Example

javascript
import axios from "axios";

const fetchPostsWithAxios = async () => {
  try {
    const response = await axios.get(
      "https://jsonplaceholder.typicode.com/posts"
    );
    console.log("Posts fetched using axios:", response.data);
  } catch (error) {
    console.error("Error fetching posts with axios:", error.message);
  }
};

fetchPostsWithAxios();

Key Features of axios

  1. Automatic JSON Parsing: The response data is parsed automatically.
  2. Comprehensive Error Handling: Axios rejects the promise for non-2xx status codes, simplifying error handling.
  3. Timeout Support: Provides built-in support for request timeouts.
  4. Shorter Syntax: A cleaner and more concise API compared to fetch.

Pros of axios

  • Better error handling out of the box.
  • Automatic transformation of response data to JSON.
  • Built-in support for features like timeouts and request cancellation.
  • Supports advanced configurations like interceptors for pre-processing requests or responses.

Cons of axios

  • Requires installation as a third-party dependency.
  • Slightly larger bundle size compared to using fetch.

Key Differences Between fetch and axios

Featurefetchaxios
Native to JavaScriptYesNo (third-party dependency)
JSON ParsingManualAutomatic
Error HandlingManualBuilt-in
Timeout SupportCustom implementation requiredBuilt-in
SyntaxVerbose for advanced use casesCleaner and more concise
Advanced FeaturesLimitedInterceptors, cancellation, etc.

When to Choose fetch

  • Small Projects: When you want to minimize dependencies.
  • Simple Use Cases: For basic GET/POST requests without complex requirements.
  • Browser Compatibility: When working in environments where external libraries are restricted.

Example Use Case

You’re building a static website that fetches and displays posts without additional error handling or timeout requirements.


When to Choose axios

  • Complex Use Cases: When you need features like timeouts, interceptors, or automatic JSON transformation.
  • Error-Resilient Applications: If robust error handling is essential.
  • Team Collaboration: For projects where a cleaner, standardized syntax improves readability and maintainability.

Example Use Case

You’re building a dynamic dashboard with multiple API calls, error-handling requirements, and potential scalability needs.


React Components for Next.js 15

Here are interactive React components to demonstrate both approaches using Next.js 15. Each component fetches data from the JSONPlaceholder API and displays the results.

Fetch Component

javascript
"use client";
import { useEffect, useState } from "react";

const FetchComponent = () => {
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState<boolean>(true); // Loading state added

  useEffect(() => {
    const fetchPosts = async () => {
      try {
        const response = await fetch(
          "https://jsonplaceholder.typicode.com/posts"
        );
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        const data = await response.json();
        setPosts(data);
      } catch (err) {
        if (err instanceof Error) {
          setError(err.message);
        } else {
          setError("An unknown error occurred");
        }
      } finally {
        setLoading(false); // Stop loading once the request is complete
      }
    };

    fetchPosts();
  }, []);

  return (
    <div className="mb-4 p-4 border rounded shadow">
      <h2 className="text-2xl font-bold mb-2">Fetch Demo</h2>
      <p className="text-gray-600 mb-4">
        <strong>Key Features:</strong>
        <ul className="list-disc ml-6">
          <li>Built-in JavaScript function, no external library required.</li>
          <li>Manual JSON parsing and error handling needed.</li>
          <li>Limited advanced features without custom implementations.</li>
        </ul>
      </p>
      {loading ? (
        <p>Loading posts...</p>
      ) : error ? (
        <p className="text-red-500">Error: {error}</p>
      ) : (
        <ul className="list-disc ml-6">
          {posts.map((post: { id: number; title: string }) => (
            <li key={post.id}>{JSON.stringify(post)}</li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default FetchComponent;

Fetch Demo

Key Features:

  • Built-in JavaScript function, no external library required.
  • Manual JSON parsing and error handling needed.
  • Limited advanced features without custom implementations.

Loading posts...

Axios Component

javascript
// pages/axios-demo.js
"use client";

import { useEffect, useState } from "react";
import axios from "axios";

const AxiosComponent = () => {
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState<boolean>(true); // Loading state added

  useEffect(() => {
    const fetchPostsWithAxios = async () => {
      try {
        const response = await axios.get(
          "https://jsonplaceholder.typicode.com/posts"
        );
        setPosts(response.data);
      } catch (err) {
        if (err instanceof Error) {
          setError(err.message);
        } else {
          setError("An unknown error occurred");
        }
      } finally {
        setLoading(false); // Stop loading once the request is complete
      }
    };

    fetchPostsWithAxios();
  }, []);

  return (
    <div className="mb-4 p-4 border rounded shadow">
      <h2 className="text-2xl font-bold mb-2">Axios Demo</h2>
      <p className="text-gray-600 mb-4">
        <strong>Key Features:</strong>
        <ul className="list-disc ml-6">
          <li>Automatic JSON parsing—data is ready to use.</li>
          <li>Built-in error handling for non-2xx status codes.</li>
          <li>Supports advanced features like timeouts and interceptors.</li>
        </ul>
      </p>
      {loading ? (
        <p>Loading posts...</p>
      ) : error ? (
        <p className="text-red-500">Error: {error}</p>
      ) : (
        <ul className="list-disc ml-6">
          {posts.map((post: { id: number; title: string }) => (
            <li key={post.id}>{JSON.stringify(post)}</li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default AxiosComponent;

Axios Demo

Key Features:

  • Automatic JSON parsing—data is ready to use.
  • Built-in error handling for non-2xx status codes.
  • Supports advanced features like timeouts and interceptors.

Loading posts...


Conclusion

Both fetch and axios are effective tools for API calls in JavaScript. The React components above illustrate their implementation in a Next.js 15 environment. Depending on your project’s complexity and requirements, choose the tool that best suits your needs.