← All unpacks
CodeVetter · Repo Unpack comparison

axios vs requests

axios scanned at 56a5f1a (2026-09-16) · requests at 611c616 (2026-09-21) · codevetter codevetter 1.12.0

The default HTTP clients of JS and Python — promise-chain interceptors vs session-based synchronous calls.

axios/axiospsf/requests
Files scanned457124
Size2.7 MB1.5 MB
Primary source rootlib/src/
Top languageJavaScript (216 files)Python (37 files)
Packageaxios v1.20.0requests v{attr = "requests.__version__.__version__"}
Structural health9.2/10 avg, 3 hotspots7.7/10 avg, 5 hotspots
Test signalmissingmissing

Architectures

axios

axios is the promise-based HTTP client library for browsers and Node.js, shipped as ESM source in `lib/` and Rollup-built UMD/ESM/CJS bundles in `dist/`. Its distinguishing shape is a single request pipeline (`Axios._request` → interceptors → `dispatchRequest` → adapter) that fans out to three interchangeable adapters — XHR, Node HTTP/HTTP2, and Fetch — selected by capability probe rather than environment name. This particular fork/branch (v1.x at 1.20.0) is unusually security-hardened: config reads go through own-property guards (`utils.getSafeProp`, `utils.toSafeFlatObject`), merges produce null-prototype objects, and there is a 94KB `THREATMODEL.md` plus a 1600-line prototype-pollution test suite. It is consumed by application developers as a dependency, and its contributor surface is governed by `AGENTS.md` plus a pre-release changelog/docs staging workflow.

requests

Requests is the PSF-maintained Python HTTP client library (`v2.34.2`, `src/requests/__version__.py`) that wraps urllib3 in a human-friendly API: `requests.get(...)` returns a `Response` with `.text`, `.json()`, `.cookies`, and `.raise_for_status()`. It is a pure-library distribution — no CLI, no server, no database — whose entire user surface is the seven module-level verb functions in `api.py` plus the `Session` object that persists cookies, auth, proxies, and a urllib3 connection pool across calls. What is distinctive in this commit is how much of the codebase is now type-machinery and hardening rather than new features: a private `_types.py` with `TypedDict` kwargs unpacking, pyright in `strict` mode over `src/requests/`, a pinned/hash-locked GitHub Actions setup audited by zizmor, and an explicit anti-LLM contribution policy. The architecture is deliberately layered so that the transport is swappable: `Session.mount(prefix, adapter)` is the single extension seam that every custom TLS, retry, or mock-transport integration in the ecosystem hangs off.

System maps

axios

The public ESM entry is `index.js`, which unwraps the default instance built by `lib/axios.js` and re-exports its statics as named exports; CJS consumers get the Rollup-built `dist/node/axios.cjs`. Domain logic lives in `lib/core/` (Axios class, dispatch, merge, headers, errors, interceptors), I/O in `lib/adapters/`, environment selection in `lib/platform/` (Node by default, browser via package.json `browser` aliasing), and generic utilities in `lib/helpers/`. There is no storage layer — the only persistent state is browser cookies read for XSRF (`lib/helpers/cookies.js`) and pooled HTTP/2 sessions (`lib/helpers/Http2Sessions.js`). Build is `gulp clear && rollup -c` producing five bundles; tests are Vitest with three projects (unit/browser/browser-headless) plus packed-tarball smoke and module suites. Deployment shape is an npm package published on `v1.*.*` tags with provenance.

requests

There is no application entrypoint — the package root `src/requests/__init__.py` is the runtime boundary, and it does dependency-compatibility checking, optional pyOpenSSL SNI injection, and re-export of the public API before anything else runs. Beneath it sit four layers: the stateless verb wrappers (`api.py`), the stateful `Session` (`sessions.py`), the request/response value objects (`models.py`), and the urllib3-backed transport (`adapters.py`). Cross-cutting support lives in `utils.py` (proxies, netrc, header validation, length probing), `cookies.py` (a `CookieJar`/`MutableMapping` hybrid), `structures.py` (`CaseInsensitiveDict`, `LookupDict`), and `exceptions.py`. There is no storage layer: the only persistent state is the in-memory `RequestsCookieJar` on a `Session` and urllib3's connection pools. Build is setuptools via `pyproject.toml`; test/lint/typecheck/publish are four separate GitHub Actions workflows, and distribution is a Trusted-Publishing PyPI upload on `v*` tags.

Repository structure

axios

  • tests/ — 162 files
  • docs/ — 155 files
  • lib/ — 73 files
  • examples/ — 17 files
  • .github/ — 14 files
  • sandbox/ — 3 files
  • .husky/ — 1 files
  • scripts/ — 1 files

requests

  • tests/ — 42 files
  • docs/ — 25 files
  • src/ — 20 files
  • .github/ — 19 files
  • ext/ — 2 files