The architecture of Axios, x-rayed
Axios has been downloaded billions of times, and its x-ray explains the longevity: a core/ that knows nothing about environments, an adapters/ package where xhr.js (browser), http.js (Node), and fetch.js are interchangeable implementations of one contract, and a platform/ module that isolates every environment check.
archsteer xray v0.4.1 against axios/axios@e435384 (lib/) on 2026-07-05. Read-only static analysis — no code executed, no architecture rules declared. Structure, not judgment.Module dependency graph
Top 9 modules by connectivity; an arrow means "imports from".
graph LR
m0["adapters"]
m1["axios"]
m2["cancel"]
m3["core"]
m4["defaults"]
m5["env"]
m6["helpers"]
m7["platform"]
m8["utils"]
m0 --> m2
m0 --> m3
m0 --> m4
m0 --> m5
m0 --> m6
m0 --> m7
m0 --> m8
m1 --> m0
m1 --> m2
m1 --> m3
m1 --> m4
m1 --> m5
m1 --> m6
m1 --> m8
m2 --> m3
m3 --> m0
m3 --> m2
m3 --> m4
m3 --> m6
m3 --> m8
m4 --> m3
m4 --> m6
m4 --> m7
m4 --> m8
m6 --> m2
m6 --> m3
m6 --> m5
m6 --> m7
m6 --> m8
m7 --> m6
m8 --> m6Components by module
Most connected components
Top 20 of 66 by exported API surface and dependency count.
| Component | Module | Key exports |
|---|---|---|
adapters/http.js | adapters | __setProxy, __isNodeEnvProxyEnabled, __isSameOriginRedirect, default |
axios.js | axios | default |
adapters/fetch.js | adapters | getFetch, default |
adapters/xhr.js | adapters | default |
core/Axios.js | core | default |
helpers/resolveConfig.js | helpers | default |
defaults/index.js | defaults | default |
core/dispatchRequest.js | core | dispatchRequest, default |
helpers/toFormData.js | helpers | DEFAULT_FORM_DATA_MAX_DEPTH, default |
adapters/adapters.js | adapters | default |
helpers/formDataToStream.js | helpers | default |
helpers/progressEventReducer.js | helpers | progressEventReducer, progressEventDecorator, asyncDecorator |
core/buildFullPath.js | core | buildFullPath, default |
helpers/buildURL.js | helpers | encode, buildURL, default |
helpers/fromDataURI.js | helpers | fromDataURI, default |
core/transformData.js | core | transformData, default |
helpers/toURLEncodedForm.js | helpers | toURLEncodedForm, default |
core/AxiosHeaders.js | core | default |
core/AxiosError.js | core | REDACTED, default |
core/mergeConfig.js | core | mergeConfig, default |
Declared runtime dependencies
What the structure teaches
Three adapters, one contract
adapters/http.js, xhr.js, and fetch.js are the three most connected components in the graph — full parallel implementations of request dispatch for Node, legacy browsers, and modern runtimes. The adapter interface is why fetch support could be added in 2024 without touching the core.
Interceptors are the request pipeline
core/Axios.js doesn't call an adapter directly; it builds a promise chain of request interceptors → dispatch → response interceptors. Features like auth refresh and logging live in userland as chain links rather than as framework options — a tiny mechanism carrying an enormous ecosystem.
platform/ is the only place allowed to sniff
Environment detection (browser vs Node vs workers, FormData and Blob availability) is quarantined in platform/. Core and helpers import capabilities from there instead of checking globals — which is what keeps 66 components coherent across every JavaScript runtime.
X-ray your own repo
This page is unedited archsteer xray output plus commentary. The same map of your codebase takes one command, runs locally, and never sends code anywhere: pip install archsteer && archsteer xray
FAQ
How is Axios structured internally?
In three rings: core/ (the Axios class, interceptor chains, config merging — environment-agnostic), adapters/ (interchangeable dispatchers: http.js for Node, xhr.js and fetch.js for browsers/modern runtimes), and helpers/ plus platform/ for utilities and quarantined environment detection. 66 components with only 4 runtime dependencies.
How does Axios work in both the browser and Node.js?
Through its adapter pattern: the core builds a normalized request config and hands it to whichever adapter the environment supports — XMLHttpRequest or fetch in browsers, the http/https modules in Node. All environment checks are centralized in platform/, so the rest of the codebase never branches on runtime.
How was this architecture map generated?
By running `archsteer xray` (an open-source, MIT-licensed CLI) against the lib/ directory of the public GitHub repo — read-only static analysis, no code executed. Reproduce it with `pip install archsteer && archsteer xray`.
More x-rays
The architecture of FastAPI, x-rayed
An auto-generated architecture map of FastAPI: 48 components across 28 modules, the module…
The architecture of Flask, x-rayed
An auto-generated architecture map of Flask: 24 components, the sansio core split, bluepri…
The architecture of HTTPX, x-rayed
An auto-generated architecture map of HTTPX: 23 underscore-private components, the pluggab…
The architecture of Starlette, x-rayed
An auto-generated architecture map of Starlette: 34 components, the middleware stack, and …