4 min read
I bundled the browser HTTP clients on this box: ky 2.1.0 came in at 9,777 B gzip against axios 1.20.0 at 19,559 B. On a localhost JSON GET loop, ky sat at about 365 us per request and axios at about 269 us.
Short answer: pick ky when you want a Fetch-based client at about half the gzip weight. Pick axios when you need broad adapters, upload progress, or the older XHR path. No affiliate links in this post.
| Browser build (esbuild minify) | Minified | gzip -9 |
|---|---|---|
| ky.get().json() | 28,589 B | 9,777 B |
| axios.get().then | 51,098 B | 19,559 B |
| ky.create() | 28,682 B | 9,817 B |
| axios.create() | 51,187 B | 19,598 B |
ky was about 2.0× smaller gzip on both the one-shot and create entries. Track shipped weight with size-limit vs bundlesize. Mock the same clients in tests with msw vs nock.
| Path (500 sequential JSON GETs, median of 9) | ky | axios |
|---|---|---|
| Local http.Server, 32-byte body | 182.714 ms (365 us/req) | 134.455 ms (269 us/req) |
On this box axios completed the sequential loop about 1.36× faster. That does not erase a ~10 KB gzip gap on the browser build. Request harness notes sit next to my Jest vs Vitest write-up when I pull these clients into a test runner.
| Situation | My pick |
|---|---|
| Browser app on Fetch, watch the gzip budget | ky |
| Need axios interceptors / upload progress / older Node | axios |
| New greenfield Fetch-first client | ky |
| Migrating a large axios codebase | stay on axios unless size is the blocker |
| Bundle budget under about 12 KB gzip for HTTP | ky |
Bottom line: ky 2.1.0 shipped 9.8 KB gzip against axios 1.20.0 at 19.6 KB, while axios won the sequential localhost JSON loop (269 vs 365 us/req). Who should not switch: teams already deep in axios adapters and interceptors — rewrite cost beats a 10 KB gzip win if size is not the constraint. Validate payloads with Zod vs Valibot. Unused-export cleanup: knip vs depcheck.
How this was made: I installed ky and axios on the ShopperCove box, measured esbuild minify+gzip browser sizes, timed sequential localhost JSON GETs, and recorded the JSON. The write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 6 Oct 2026 ~01:01-01:02 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0 with fetch). ky 2.1.0 vs axios 1.20.0, esbuild 0.28.2. Fixture /workspace/bench-ky-axios/: browser entries ky.get().json vs axios.get().then; create with prefix/baseURL. Speed: local http.Server 32-byte JSON, 500 sequential GETs x 9 rounds (median) after warm. Medians: gzip 9,777 vs 19,559 B; create 9,817 vs 19,598 B; loop 182.714 vs 134.455 ms (365 vs 269 us/req). Disk ~720 KB vs ~2.2 MB. Raw: res-bundle.json, res-speed.json. Not tested: XHR, upload progress, interceptors under load, retries at scale, React Query/SWR, HTTPS/HTTP2, multipart. No affiliate.