axios/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.
- `index.js` is the ESM public entry: it imports the default instance from `lib/axios.js` and destructures 18 statics (`Axios`, `AxiosError`, `CanceledError`, `CancelToken`, `VERSION`, `toFormData`, `AxiosHeaders`, `HttpStatusCode`, `formToJSON`, `getAdapter`, `mergeConfig`, `create`, …) so ESM and CJS named-import shapes stay identical.
- `createInstance(defaultConfig)` in `lib/axios.js` binds `Axios.prototype.request` to a fresh `Axios` context via `helpers/bind.js`, then copies both prototype and context onto the callable with `utils.extend(..., {allOwnKeys: true})`, which is why `axios(...)` is callable *and* carries `.get`/`.interceptors`/`.defaults`.
- Runtime boundary between Node and browser is resolved by package.json `browser`/`react-native` maps that swap `lib/adapters/http.js` → `lib/helpers/null.js`, `lib/platform/node/index.js` → `lib/platform/browser/index.js`, and Node `Buffer`/`FormData` classes to null — `lib/platform/index.js` itself always imports the Node platform.
- Adapter registry `knownAdapters` maps `http` → Node adapter, `xhr` → XHR adapter, and `fetch` → an object with a `get(config)` factory (`fetchAdapter.getFetch`), so fetch is resolved lazily per-`config.env` while the other two are plain functions or `false`.
- Default adapter preference is the ordered list `['xhr', 'http', 'fetch']` set in `lib/defaults/index.js`; `getAdapter` walks it, treating `false` as 'not supported by the environment' and `undefined` as 'not available in the build' when composing the `ERR_NOT_SUPPORT` message.
- The Node adapter is the heaviest module (1490 lines) and pulls in `http`, `https`, `http2`, `zlib`, `stream`, `path`, plus the four runtime deps `follow-redirects`, `form-data` (indirectly), `https-proxy-agent`, and `proxy-from-env`.
- Build emits five artifacts from two inputs: `dist/esm/axios.js` (ESM, from `index.js`), `dist/axios.js` (UMD, Babel-transpiled to ES5, from `lib/axios.js`), `dist/browser/axios.cjs`, and `dist/node/axios.cjs` (Babel-targeted at Node 12, with `proxy-from-env` deliberately inlined by `nodeCjsExternal`).
- `gulp version` (run via the `preversion` npm script) regenerates `lib/env/data.js` from package.json and rewrites the `contributors` array by calling the GitHub API through an axios instance built in `scripts/axios-build-instance.js` using `GITHUB_TOKEN`.
- Test commands are Vitest-project-scoped: `npm run test:vitest:unit` (node env, `tests/unit/**/*.test.js`), `test:vitest:browser` (chromium headed), and `test:vitest:browser:headless` (chromium+firefox+webkit via Playwright), all declared in `vitest.config.js` with a 10s default `testTimeout`.
- CI order in `run-ci.yml` is: checkout → `npm ci --ignore-scripts` → lint → build → `npx playwright install --with-deps` → unit → browser headless → `npm pack` → dependency-review → upload tarball; every downstream job (`cjs-smoke`, `esm-smoke`, `cjs-module`, `esm-module`, `bun-smoke`, `deno-smoke`) `needs` that job and installs the packed tarball rather than the source tree.
- Publishing is tag-triggered (`v1.*.*`) into the `npm-publish` GitHub environment with `id-token: write` and `npm stage publish --provenance --access public`; release branches are cut by a manual `workflow_dispatch` in `release-branch.yml` with patch/minor/major + prerelease inputs.
- Supply-chain guards are separate workflows: `lockfile-lint.yml` validates HTTPS registry URLs and integrity hashes on any package.json/package-lock.json change (pinned by name, deliberately not a devDependency), `zizmor.yml` scans the Actions themselves with `permissions: {}`, and `verify-build-reproducibility.yml` does a two-pass build diff (currently `continue-on-error: true`).
- The documentation site is a separate VitePress+Vue workspace under `docs/` with its own package.json (`docs:dev`, `docs:build`, `docs:update:sponsors`, `test:search`) and 155 markdown files across localized `docs/<lang>/pages/` trees — it is not part of the library build.
- Two local dev servers exist for manual exercise: `npm start` runs `sandbox/server.js` (serves `sandbox/client.html` and an `/api` echo endpoint) and `npm run examples` runs `examples/server.js`.