ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 41

  1. Blog

ofetch vs ky: 4.1 KB vs 9.8 KB Gzip

Aditya Challa·5 October 2026·4 min read

Hands-on
On this page
  1. What I tested
  2. How much smaller is ofetch?
  3. Does plain GET speed matter?
  4. Do the APIs behave the same?
  5. Which one should you pick?
  6. Sources
  7. Related

I bundled the two common fetch wrappers on this box: ofetch 1.5.1 came out at 4,057 bytes gzip, while ky 2.1.0 came out at 9,779 bytes. Against a local JSON server, ofetch.create averaged about 122 µs per request versus about 263 µs for ky.create.

Short answer: pick ofetch when you want a smaller auto-parsing client (Nuxt / unjs stack). Keep ky when you want Response-first control, stricter TypeScript around HTTPError, and the default retry=2 policy on safe methods. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 6 Oct 2026 about 02:15 IST.
  • Versions: ofetch 1.5.1, ky 2.1.0, Node 22.20.0, esbuild 0.28.2 browser ESM minify + gzip -9.
  • Inputs: local http.Server JSON payload (~32 object fields via 20 items). Speed: 800 sequential GETs, median of 9 rounds, two runs with library order reversed. Scripts in /workspace/bench-ofetch-ky/.
  • Findings: ofetch 10,114/4,057 B vs ky 28,594/9,779 B; create wrappers 10,127/4,070 vs 28,611/9,787. Plain GET µs/req: ofetch 183.8 / 129.7 vs ky 179.8 / 203.5. create µs/req: ofetch 118.8 / 125.8 vs ky 300.4 / 225.7.
  • One surprise: ofetch.FetchError on 404 already exposed parsed .data; ky.HTTPError needed a separate e.response.json() read, and my first attempt saw a null body after .json() had already been requested on the failing call.
  • Not tested: browsers, interceptors/hooks under load, upload streams, AbortSignal races, or ofetch's native Node dispatcher path beyond undici-backed global fetch.

How much smaller is ofetch?

Build (esbuild browser minify)Minifiedgzip -9
ofetch10,114 B4,057 B
ky28,594 B9,779 B
ofetch.create wrapper10,127 B4,070 B
ky.create wrapper28,611 B9,787 B

About 2.4× smaller gzip for ofetch. Track client cost the same way as size-limit vs bundlesize. If you are already comparing ky to axios, see ky vs axios. Cookie helpers that often sit next to API clients show up in cookie-es vs cookie.

Does plain GET speed matter?

Call cost (800 GETs, median of 9, 2 order-reversed runs, µs/req)ofetchky
Absolute URL + auto/manual JSON183.8 / 129.7179.8 / 203.5
create() + relative path118.8 / 125.8300.4 / 225.7

Plain GETs were within noise across order-reversed runs. ofetch.create stayed clearly cheaper on this box (~2×). That gap is still tiny next to real network RTT. If your bottleneck is cloning response payloads instead of fetching them, compare klona vs structuredClone. Hashing cache keys sits next to ohash vs object-hash.

Do the APIs behave the same?

Topicofetch 1.5.1ky 2.1.0
Success JSONauto-parsed objectResponse; call .json()
Query stringquery: { a, b }searchParams: { a, b }
Client factoryofetch.create({ baseURL })ky.create({ prefix })
404 errorFetchError with .status + .dataHTTPError with .response
Retry default12 on safe methods

Query encoding matched on my echo fixture. Base-path clients both returned { a: 1 }. Error shapes did not. For URL joining before the request, see ufo vs URL. Soft JSON parse helpers show up in destr vs superjson.

Which one should you pick?

SituationMy pick
Nuxt / unjs stack, want auto JSONofetch
Smallest browser client for JSON APIsofetch
Want Response / ReadableStream controlky
Prefer retry=2 on GET by defaultky
Migrating from axios with interceptorsre-check ky first (ky vs axios)

Bottom line: ofetch 1.5.1 was 4,057 B gzip versus 9,779 B for ky 2.1.0, and ofetch.create was about 2× cheaper per local request on this box. Who should not switch: codebases that treat every call as a Response object, or teams standardized on ky's HTTPError + retry defaults. Shell-out helpers in the same decision lane sit next to tinyexec vs execa.

How this was made: I installed both packages on the ShopperCove box, measured esbuild browser bundles, timed sequential GETs against a local http.Server in two order-reversed runs, and compared JSON/text/404/query/create behavior. The JSON results sit next to the scripts. The write-up was drafted with AI help and checked against that output.

Sources

  • https://github.com/unjs/ofetch
  • https://github.com/sindresorhus/ky
  • https://www.npmjs.com/package/ofetch
  • https://www.npmjs.com/package/ky

Related

  • https://www.shoppercove.com/blog/ky-vs-axios
  • https://www.shoppercove.com/blog/size-limit-vs-bundlesize
  • https://www.shoppercove.com/blog/cookie-es-vs-cookie
  • https://www.shoppercove.com/blog/ufo-vs-url
  • https://www.shoppercove.com/blog/destr-vs-superjson
  • https://www.shoppercove.com/blog/klona-vs-structuredclone
  • https://www.shoppercove.com/blog/ohash-vs-object-hash
  • https://www.shoppercove.com/blog/tinyexec-vs-execa
ofetchkybundle sizefetch wrapperperformancejavascripthttp clientbenchmarking

Lab evidence

What I found running this

Hands-on on ShopperCove box 6 Oct 2026 ~02:15 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). ofetch 1.5.1 vs ky 2.1.0, esbuild 0.28.2 browser ESM minify + gzip -9. Size: ofetch 10,114/4,057 B vs ky 28,594/9,779 B; create 10,127/4,070 vs 28,611/9,787. Speed (800 sequential local JSON GETs, 9-round median, order-reversed, µs/req): plain ofetch 183.8 / 129.7 vs ky 179.8 / 203.5; create ofetch 118.8 / 125.8 vs ky 300.4 / 225.7. Behavior: ofetch auto-JSON + FetchError.data on 404; ky Response/.json() + HTTPError; query/searchParams matched; create baseURL vs prefix both worked. Not tested: browsers, hooks under load, upload streams, AbortSignal races. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 64

    Ky vs Axios: 9.8 KB vs 19.6 KB Gzip

    5 Oct 2026

  • Plate 09

    ohash vs object-hash: 10x Faster, 3.3 KB vs 11 KB

    5 Oct 2026

  • Plate 55

    Klona vs structuredClone: 1.4M vs 225k Clones per Second

    5 Oct 2026

On this page

  1. What I tested
  2. How much smaller is ofetch?
  3. Does plain GET speed matter?
  4. Do the APIs behave the same?
  5. Which one should you pick?
  6. Sources
  7. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove