What is Axios? A Practical HTTP Client for Modern Apps
Make HTTP requests with Axios — a Promise-based client more powerful than fetch. Walkthrough covers instances, interceptors, error handling and query params.
Axios is a Promise-based HTTP client that runs in both the browser and Node.js — for years the industry standard. It fills in fetch's gaps with automatic JSON parsing, request/response interceptors, an instance pattern and richer error handling, making the API layer of modern apps faster to ship. This guide walks through how to install Axios and configure it in real-world scenarios.
What is Axios?
A Promise-based HTTP client that works in both the browser and Node.js. Compared to fetch it adds automatic JSON parsing, shortcuts for GET/POST/PUT/DELETE and a more robust error model. It's one of the most popular choices for an app's API layer.
- Promise-based — async/await friendly
- Single API for browser + Node.js
- Automatic JSON conversion
- Plays nicely with REST APIs
Why Use Axios?
fetch is standard, but as projects grow you end up repeating configuration. Axios centralizes that configuration through instances and interceptors.
- Cleaner syntax — short and readable
- Automatic JSON parsing
- Request/response interceptors
- Built-in timeout management
- Great fit for REST APIs
Installation
Add it with one command as a runtime dependency.
npm install axiosBasic GET Request
axios.get returns a single Promise; response.data already contains parsed data.
import axios from "axios";
const fetchUsers = async () => {
const res = await axios.get("/api/users");
return res.data;
};POST Request
The second argument is the body; Axios serializes the object to JSON and sets the right Content-Type header.
await axios.post("/api/users", {
name: "Ada",
email: "ada@dev.com",
});GET with TypeScript
Axios accepts generic types. That makes response.data the model you expect instead of any, giving your components autocomplete and type safety.
import axios from "axios";
type User = {
id: string;
name: string;
email: string;
};
export async function getUsers() {
const res = await axios.get<User[]>("/api/users");
return res.data;
}
const users = await getUsers();
users[0].email; // stringPOST with TypeScript
Type the request body and response model separately. This is especially useful for forms, auth flows and create/update screens where field names drift easily.
import { api } from "@/lib/api";
type CreateUserInput = {
name: string;
email: string;
};
type User = CreateUserInput & {
id: string;
};
export async function createUser(input: CreateUserInput) {
const res = await api.post<User>("/users", input);
return res.data;
}
await createUser({
name: "Ada",
email: "ada@dev.com",
});Axios Instance (IMPORTANT)
Collect repeated settings into an instance: baseURL, timeout, common headers. Using a single instance everywhere removes configuration drift.
import axios from "axios";
export const api = axios.create({
baseURL: "https://example.com/api",
timeout: 5000,
headers: { Accept: "application/json" },
});
api.get("/users");Typed API Layer
Instead of spreading raw axios calls across components, write small typed functions. This shape plugs cleanly into React Query, Zustand or server actions.
import { api } from "@/lib/api";
type ApiResponse<T> = {
data: T;
message?: string;
};
type User = {
id: string;
name: string;
role: "admin" | "editor" | "viewer";
};
export async function getUser(id: string) {
const res = await api.get<ApiResponse<User>>(`/users/${id}`);
return res.data.data;
}Interceptors
Use interceptors to globally hook into the request/response lifecycle. They're perfect for attaching tokens, central error handling and logging.
api.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${getToken()}`;
return config;
});
api.interceptors.response.use(
(response) => response,
(error) => {
console.error(error);
return Promise.reject(error);
}
);Error Handling
Unlike fetch, Axios automatically rejects on 4xx/5xx codes. Catch with try/catch and inspect error.response for details.
type ApiError = {
message: string;
code?: string;
};
try {
const res = await api.get("/users");
} catch (err) {
if (axios.isAxiosError<ApiError>(err)) {
console.log(err.response?.status, err.response?.data);
}
}Request Config
You can override settings on a per-request basis: headers, timeout, params, withCredentials and more.
await api.get("/users", {
headers: { "X-Trace-Id": "abc" },
timeout: 2000,
withCredentials: true,
});Query Params
The params field accepts an object and appends ?key=value to the URL. For complex shapes you can supply a paramsSerializer.
await api.get("/posts", {
params: { page: 1, limit: 10 },
});
// → /posts?page=1&limit=10Use Cases
Where Axios shines:
- Consuming REST APIs
- Authentication flows (token interceptor)
- Typed API services with TypeScript
- Modern frontend frameworks
- Working alongside React Query
Summary
Axios is a strong, flexible library that simplifies HTTP requests. Compared to fetch it offers cleaner syntax, more reliable error handling and better scalability. From small scripts to enterprise apps, it remains the go-to HTTP client of the modern JavaScript ecosystem.
Frequently Asked Questions
Common questions about this topic.
Axios or fetch?
fetch is built-in; Axios adds extras. For tiny projects fetch is enough — but when you need interceptors, instances and cleaner error handling, Axios pulls ahead.
How big is Axios?
Roughly ~13kB gzip. With tree-shaking the impact is minimal. For performance-critical mobile work fetch may be preferable; for most web apps it's negligible.
Does Axios work with SSR?
Yes — same API on Node.js. In frameworks like Next.js you can use it for server-side data fetching. For cookie-based auth, configure withCredentials or pass custom headers.
How do I do token refresh?
Catch 401s in the response interceptor, call your refresh endpoint, then retry the original request with the new token. A small state object queues pending requests during refresh.
Can I use Axios with React Query?
Yes — that's a common pattern. Axios handles the HTTP layer; React Query handles cache/state. Just call axios.get inside your queryFn.
Related Posts
Other infographics on connected topics.
- ToolsFrontend
What is Vite? Next-Generation Frontend Tooling
Vite ships an ESM-native dev server that starts instantly and lightning-fast HMR. Walk through setup, the plugin system, production builds and a Webpack comparison.
- FrontendTools
What is Zod? Type-Safe Validation for Modern Apps
Generate runtime validation from TypeScript types with Zod. Schema definitions, parse, safeParse, type inference and React Hook Form integration.
- ReactFrontend
What is React Query? Mutation Guide with Axios and TypeScript
Use React Query (TanStack Query) with an Axios baseURL, login mutation, create user and update user hooks in TypeScript.
Discover more developer infographics
Visit the homepage so you don't miss new content.
See all infographics