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
javascriptimport 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
- Built-In Functionality:
fetch
is native to JavaScript, requiring no external dependencies. - Simple Syntax for Basic Calls: Works well for straightforward requests.
- Manual Error Handling: Developers must handle HTTP errors explicitly.
- 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
javascriptimport 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
- Automatic JSON Parsing: The response data is parsed automatically.
- Comprehensive Error Handling: Axios rejects the promise for non-2xx status codes, simplifying error handling.
- Timeout Support: Provides built-in support for request timeouts.
- 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
Feature | fetch | axios |
---|---|---|
Native to JavaScript | Yes | No (third-party dependency) |
JSON Parsing | Manual | Automatic |
Error Handling | Manual | Built-in |
Timeout Support | Custom implementation required | Built-in |
Syntax | Verbose for advanced use cases | Cleaner and more concise |
Advanced Features | Limited | Interceptors, 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.