Lo que Axios sigue ofreciéndote frente a Fetch
La Fetch API ha madurado significativamente. Está integrada en todos los navegadores modernos, disponible de forma nativa en Node.js desde la v18 a través de Undici, y es capaz de manejar JSON, cancelación de solicitudes y streaming. Para muchas peticiones de API en el frontend, realmente es suficiente.
Entonces, ¿por qué los equipos siguen recurriendo a Axios? No por costumbre, sino porque Axios todavía resuelve problemas específicos de experiencia del desarrollador que Fetch deja en tus manos. Aquí es donde esa diferencia se hace evidente.
Puntos clave
- Fetch se resuelve con éxito incluso ante respuestas 4xx y 5xx, obligando a comprobar manualmente
response.oken cada solicitud. - Los interceptores de Axios centralizan aspectos transversales como tokens de autenticación, logging y normalización de errores sin necesidad de código repetitivo en cada petición.
- La configuración compartida mediante
axios.create()facilita el trabajo con múltiples APIs que requieren distintas URLs base, cabeceras o timeouts. - El seguimiento del progreso de subidas y las opciones de timeout integradas siguen siendo exclusivas de Axios, algo que Fetch no puede igualar de forma nativa.
- Para proyectos pequeños con necesidades HTTP mínimas, Fetch es la opción adecuada por defecto, sin dependencias.
Axios vs Fetch: dónde están las diferencias reales
1. Manejo de errores HTTP que funciona por defecto
Fetch solo rechaza ante fallos de red. Una respuesta 404 o 500 se resuelve con éxito — tienes que comprobar tú mismo response.ok en cada ocasión.
// Fetch — debes comprobarlo manualmente
const res = await fetch('/api/user');
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);
const data = await res.json();
// Axios — rechaza automáticamente ante 4xx/5xx por defecto
const { data } = await axios.get('/api/user');
En aplicaciones grandes con docenas de endpoints, esa comprobación manual se convierte en código repetitivo. Axios elimina la mayor parte de él por defecto.
2. Interceptores de solicitud y respuesta integrados
Esta es la característica que la mayoría de los desarrolladores menciona al elegir Axios. Los interceptores permiten incorporar lógica — tokens de autenticación, logging, normalización de errores — una sola vez, de forma global, sin tocar las solicitudes individuales.
axios.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${getToken()}`;
return config;
});
axios.interceptors.response.use(
response => response,
error => {
if (error.response?.status === 401) redirectToLogin();
return Promise.reject(error);
}
);
Con Fetch puedes simular esto envolviendo fetch() en una función personalizada. Pero ese wrapper no es componible, no es apilable, y eres tú quien tiene que mantenerlo.
3. Configuración compartida con instancias de Axios
Axios te permite crear instancias aisladas con URLs base, cabeceras y timeouts predefinidos — un patrón realmente útil cuando tu aplicación se comunica con múltiples APIs.
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 8000,
headers: { 'X-App-Version': '2.1.0' },
});
Replicar esto de forma limpia con Fetch requiere una clase wrapper o una función factory. Es factible, pero es trabajo adicional que asumes.
Discover how at OpenReplay.com.
4. Seguimiento del progreso de subida
Fetch todavía no dispone de una API nativa estandarizada para el progreso de subidas en navegadores. Axios expone onUploadProgress directamente, respaldada internamente por XMLHttpRequest en los navegadores.
await axios.post('/upload', formData, {
onUploadProgress: e => {
if (e.total) {
console.log(`${Math.round((e.loaded / e.total) * 100)}%`);
}
},
});
Si necesitas progreso de subida con Fetch exclusivamente, vuelves a tener que usar XMLHttpRequest directamente. Eso es una verdadera regresión.
5. Configuración de timeout sin código repetitivo de AbortController
Axios acepta una opción timeout directamente. Fetch requiere que conectes manualmente AbortController y setTimeout — funciona, pero añade ruido al código.
// Axios
await axios.get('/api/data', { timeout: 5000 });
// Equivalente con Fetch
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), 5000);
try {
const res = await fetch('/api/data', { signal: controller.signal });
} finally {
clearTimeout(id);
}
Los entornos modernos también admiten AbortSignal.timeout(), que acorta esto considerablemente, y el soporte en navegadores ya está ampliamente disponible.
Comparación rápida: Axios vs Fetch API
| Capacidad | Fetch | Axios |
|---|---|---|
| Rechazo de errores HTTP | Comprobación manual de response.ok | Automático por defecto |
| Interceptores | Requiere wrapper personalizado | Integrado |
| Instancias compartidas | Patrón factory manual | axios.create() |
| Progreso de subida | No soportado nativamente | onUploadProgress |
| Timeout de solicitud | AbortController + setTimeout | Opción timeout |
| Tamaño del bundle | 0 KB (nativo) | ~15 KB gzipped |
Conclusión
Fetch no es insuficiente. Para clientes HTTP simples en JavaScript — unos pocos endpoints, sin lógica compartida de autenticación, sin progreso de subidas — es la opción adecuada por defecto. Sin dependencias, sin sobrecarga.
Pero Axios se gana su lugar cuando las solicitudes API de tu frontend ganan en complejidad. Los interceptores, las instancias compartidas, el manejo automático de errores y el progreso de subidas no son funciones que echarás de menos hasta que las necesites — y entonces las querrás integradas, no implementadas a mano. Eso es lo que Axios sigue ofreciéndote.
Preguntas frecuentes
Depende de la complejidad del proyecto. Para un puñado de solicitudes sencillas, Fetch es suficiente y evita una dependencia. Para aplicaciones con autenticación compartida, manejo centralizado de errores, múltiples clientes API o requisitos de progreso de subida, Axios ahorra una cantidad significativa de código repetitivo que de otro modo tendrías que reimplementar tú mismo.
Parcialmente. Puedes envolver fetch en una función que inyecte cabeceras o gestione errores, pero pierdes la naturaleza apilable y componible de los interceptores de Axios. Cada nueva preocupación requiere modificar el wrapper directamente, y encadenar múltiples interceptores independientes se vuelve engorroso. La mayoría de los equipos que lo intentan acaban reconstruyendo una versión más pequeña y menos probada de Axios.
No exactamente. Axios soporta el progreso de subida y descarga en Node.js, pero la implementación difiere de los navegadores porque Node no utiliza XMLHttpRequest. Los eventos de progreso en navegadores suelen ser más fluidos y granulares, mientras que algunos escenarios de subida en Node.js — especialmente subidas con FormData — tienen limitaciones según el adaptador y el runtime.
Ambas son sólidas. Ky es un wrapper ligero basado en Fetch que añade reintentos, hooks y timeouts manteniéndose ligero. Got es rico en funciones pero está limitado a Node. Axios sigue siendo popular porque funciona tanto en navegadores como en entornos Node con una sola API, cuenta con un amplio soporte en el ecosistema y resulta familiar para la mayoría de los desarrolladores de JavaScript.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.