Axios Default XHR Adapter Architecture Explained
This article explores the role of the default XHR adapter in Axios, a
core component responsible for executing HTTP requests in browser
environments. You will learn how the adapter pattern enables Axios to
maintain an isomorphic architecture, how the XHR adapter translates
Axios request configurations into native XMLHttpRequest
calls, and the specific browser-level features—such as progress tracking
and request cancellation—it manages under the hood.
The Role of Adapters in Axios
Axios is an isomorphic HTTP client, meaning the exact same API can be used in both client-side browser environments and server-side Node.js applications. To achieve this without polluting the core codebase with environment-specific logic, Axios uses the Adapter Design Pattern.
In this architecture, high-level features—such as request/response interceptors, automatic JSON serialization, and response transforms—are decoupled from the underlying network transport layer. The core of Axios handles the configuration and lifecycle, while an adapter handles the actual network dispatch.
What is the Default XHR Adapter?
The default XHR adapter (axios/lib/adapters/xhr.js) is
the transport mechanism Axios invokes when running in a browser. It is
built directly on top of the native browser XMLHttpRequest
(XHR) API.
When a request is initiated in a browser environment, Axios selects the XHR adapter by default to translate the abstract Axios request configuration object into an active browser-level HTTP request.
Key Functions of the XHR Adapter
1. Translating
Configurations to XMLHttpRequest
The adapter maps Axios configuration properties directly to
XMLHttpRequest methods and properties. This includes:
- Setting the HTTP method via
xhr.open(). - Applying custom request headers using
xhr.setRequestHeader(). - Managing authentication credentials and cross-origin cookies via
xhr.withCredentials. - Setting network timeouts via
xhr.timeout.
2. Promise Resolution and Status Handling
Native XMLHttpRequest relies on event listeners
(onload, onerror, ontimeout,
onabort). The XHR adapter wraps these events inside a
JavaScript Promise:
- Resolution: When
onloadfires, the adapter extracts the response data, status code, headers, and status text, packaging them into a standardized Axios response object. It then resolves the promise if the status code passes thevalidateStatusfunction. - Rejection: If the network fails
(
onerror), the request times out (ontimeout), or the status validation fails, the adapter generates a normalizedAxiosErrorand rejects the promise.
3. Native Progress Event Handling
One of the primary reasons Axios continues to use
XMLHttpRequest instead of the standard fetch
API for its default browser adapter is progress monitoring. The XHR
adapter binds directly to:
xhr.upload.onprogressfor tracking file and payload uploads.xhr.onprogressfor tracking download progress.
These events are passed directly to user-defined callbacks
(onUploadProgress and onDownloadProgress),
enabling accurate progress bars in user interfaces.
4. Request Cancellation
The XHR adapter integrates with modern AbortController
signals as well as legacy Axios CancelToken instances. When
an abort signal is triggered, the adapter calls
xhr.abort(), immediately terminating the network connection
and cleaning up browser resources.
Architectural Benefits
By isolating XMLHttpRequest logic inside the default XHR
adapter, Axios keeps its core logic lightweight and testable. Developers
can replace the default XHR adapter with custom implementations—such as
a fetch-based adapter or a mock adapter for unit
testing—without altering how interceptors, defaults, or response
transforms function in their applications.