Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ohmyfetch

unjs182kMITdeprecated0.4.21TypeScript support: included

Package renamed to https://github.com/unjs/ofetch

oh-my-fetch

readme

npm version npm downloads Github Actions Codecov bundle

😱 ohmyfetch

🚀 Quick Start

Install:

# npm
npm i ohmyfetch

# yarn
yarn add ohmyfetch

Import:

// ESM / Typescript
import { $fetch } from 'ohmyfetch'

// CommonJS
const { $fetch } = require('ohmyfetch')
<summary>Spoiler</summary>

✔️ Works with Node.js

We use conditional exports to detect Node.js and automatically use unjs/node-fetch-native. If globalThis.fetch is available, will be used instead. To leverage Node.js 17.5.0 experimental native fetch API use --experimental-fetch flag.

undici support

In order to use experimental fetch implementation from nodejs/undici, You can import from ohmyfetch/undici.

import { $fetch } from 'ohmyfetch/undici'

On Node.js versions older than 16.5, node-fetch will be used as the fallback.

keepAlive support

By setting the FETCH_KEEP_ALIVE environment variable to true, an http/https agent will be registered that keeps sockets around even when there are no outstanding requests, so they can be used for future requests without having to reestablish a TCP connection.

Note: This option can potentially introduce memory leaks. Please check node-fetch/node-fetch#1325.

✔️ Parsing Response

$fetch will smartly parse JSON and native values using destr, falling back to text if it fails to parse.

const { users } = await $fetch('/api/users')

For binary content types, $fetch will instead return a Blob object.

You can optionally provide a different parser than destr, or specify blob, arrayBuffer or text to force parsing the body with the respective FetchResponse method.

// Use JSON.parse
await $fetch('/movie?lang=en', { parseResponse: JSON.parse })

// Return text as is
await $fetch('/movie?lang=en', { parseResponse: txt => txt })

// Get the blob version of the response
await $fetch('/api/generate-image', { responseType: 'blob' })

✔️ JSON Body

$fetch automatically stringifies request body (if an object is passed) and adds JSON Content-Type and Accept headers (for put, patch and post requests).

const { users } = await $fetch('/api/users', { method: 'POST', body: { some: 'json' } })

✔️ Handling Errors

$fetch Automatically throw errors when response.ok is false with a friendly error message and compact stack (hiding internals).

Parsed error body is available with error.data. You may also use FetchError type.

await $fetch('http://google.com/404')
// FetchError: 404 Not Found (http://google.com/404)
//     at async main (/project/playground.ts:4:3)

In order to bypass errors as response you can use error.data:

await $fetch(...).catch((error) => error.data)

✔️ Auto Retry

$fetch Automatically retries the request if an error happens. Default is 1 (except for POST, PUT and PATCH methods that is 0)

await $fetch('http://google.com/404', {
  retry: 3
})

✔️ Type Friendly

Response can be type assisted:

const article = await $fetch<Article>(`/api/article/${id}`)
// Auto complete working with article.id

✔️ Adding baseURL

By using baseURL option, $fetch prepends it with respecting to trailing/leading slashes and query search params for baseURL using ufo:

await $fetch('/config', { baseURL })

✔️ Adding Query Search Params

By using query option (or params as alias), $fetch adds query search params to URL by preserving query in request itself using ufo:

await $fetch('/movie?lang=en', { query: { id: 123 } })

✔️ Interceptors

It is possible to provide async interceptors to hook into lifecycle events of $fetch call.

You might want to use $fetch.create to set set shared interceptors.

onRequest({ request, options })

onRequest is called as soon as $fetch is being called, allowing to modify options or just do simple logging.

await $fetch('/api', {
  async onRequest({ request, options }) {
    // Log request
    console.log('[fetch request]', request, options)

    // Add `?t=1640125211170` to query search params
    options.query = options.query || {}
    options.query.t = new Date()
  }
})

onRequestError({ request, options, error })

onRequestError will be called when fetch request fails.

await $fetch('/api', {
  async onRequestError({ request, options, error }) {
    // Log error
    console.log('[fetch request error]', request, error)
  }
})

onResponse({ request, options, response })

onResponse will be called after fetch call and parsing body.

await $fetch('/api', {
  async onResponse({ request, response, options }) {
    // Log response
    console.log('[fetch response]', request, response.status, response.body)
  }
})

onResponseError({ request, options, response })

onResponseError is same as onResponse but will be called when fetch happens but response.ok is not true.

await $fetch('/api', {
  async onResponseError({ request, response, options }) {
    // Log error
    console.log('[fetch response error]', request, response.status, response.body)
  }
})

✔️ Create fetch with default options

This utility is useful if you need to use common options across serveral fetch calls.

Note: Defaults will be cloned at one level and inherrited. Be careful about nested options like headers.

const apiFetch = $fetch.create({ baseURL: '/api' })

apiFetch('/test') // Same as $fetch('/test', { baseURL: '/api' })

💡 Adding headers

By using headers option, $fetch adds extra headers in addition to the request default headers:

await $fetch('/movies', {
  headers: {
    Accept: 'application/json',
    'Cache-Control': 'no-cache'
  }
})

🍣 Access to Raw Response

If you need to access raw response (for headers, etc), can use $fetch.raw:

const response = await $fetch.raw('/sushi')

// response.data
// response.headers
// ...

📦 Bundler Notes

  • All targets are exported with Module and CommonJS format and named exports
  • No export is transpiled for sake of modern syntax
    • You probably need to transpile ohmyfetch, destr and ufo packages with babel for ES5 support
  • You need to polyfill fetch global for supporting legacy browsers like using unfetch

❓ FAQ

Why export is called $fetch instead of fetch?

Using the same name of fetch can be confusing since API is different but still it is a fetch so using closest possible alternative. You can however, import { fetch } from ohmyfetch which is auto polyfilled for Node.js and using native otherwise.

Why not having default export?

Default exports are always risky to be mixed with CommonJS exports.

This also guarantees we can introduce more utils without breaking the package and also encourage using $fetch name.

Why not transpiled?

By keep transpiling libraries we push web backward with legacy code which is unneeded for most of the users.

If you need to support legacy users, you can optionally transpile the library in your build pipeline.

License

MIT. Made with 💖

changelog

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

v1.4.1

compare changes

🩹 Fixes

  • Remove undefined method and query/params from fetch options (#451)
  • Use response._bodyInit as fallback for react-native and qq (#398)

🏡 Chore

✅ Tests

❤️ Contributors

v1.4.0

compare changes

🚀 Enhancements

  • Support retryDelay with callback function (#372)
  • Add better message and code for timeout error (#351)
  • Allow custom global options for $fetch.create (#401)
  • Support interceptors arrays (#353)
  • Always clone and normalize options.headers and options.query (#436)

🩹 Fixes

  • Export types from node export condition (#407)
  • Use wrapper to allow patching global fetch (#377)

📖 Documentation

  • Add docs for using undici dispatcher (#389)

🌊 Types

  • Add agent and dispatcher options (node-specific) (#308)

🏡 Chore

✅ Tests

  • Add additional tests for hook errors (7ff4d11)

🤖 CI

❤️ Contributors

v1.3.4

compare changes

🚀 Enhancements

  • Export all types (#280)
  • Expose GlobalOptions type (#307)

🩹 Fixes

  • Clear abort timeout after response was received (#369)

💅 Refactors

  • Remove extra line (#374)

📖 Documentation

  • Add initial examples (#288)

📦 Build

  • Add top level react-native field (03680dd)

🏡 Chore

❤️ Contributors

v1.3.3

compare changes

🩹 Fixes

  • Augment FetchError type to include IFetchError (#279)

❤️ Contributors

v1.3.2

compare changes

🩹 Fixes

  • Hide getters from console and pass cause (905244a)

❤️ Contributors

  • Pooya Parsa (@pi0)

v1.3.1

compare changes

🏡 Chore

❤️ Contributors

  • Pooya Parsa (@pi0)

v1.3.0

compare changes

🚀 Enhancements

  • Support customizable retryStatusCodes (#109)
  • Add options field and improve formatting of errors (#270)
  • Automatically enable duplex to stream request body (#275)

🩹 Fixes

  • Avoid binding .native to $fetch (#272)
  • Skip reading body with 204 responses and HEAD requests (#171, #84)
  • Improve response body check for node 16 compatibility (64d3aed)
  • Avoid serializing buffer body (#273)
  • Move body handling out of request block (15a28fb)

💅 Refactors

  • Remove unused response?: boolean option (#223)
  • Pass all fetch context to the error (b70e6b0)
  • error: Factory pattern for getters (6139785)

📖 Documentation

  • Improve explanation about body option (#276)

🏡 Chore

  • release: V1.2.1 (bb98cb5)
  • Remove accidental raw response type addition (8589cae)

❤️ Contributors

  • Pooya Parsa (@pi0)
  • Nozomu Ikuta
  • Daniil Bezuglov

v1.2.1

compare changes

📦 Build

  • Add missing node export condition (4081170)

🏡 Chore

✅ Tests

  • Speedup with background close (567fb35)

❤️ Contributors

  • Pooya Parsa (@pi0)

v1.2.0

compare changes

🚀 Enhancements

  • Support retryDelay (#262)
  • Support timeout and AbortController (#268)

🩹 Fixes

  • Always uppercase method option (#259)
  • pkg: Fix ts type resolution for /node subpath (#256)
  • Make all createFetch options optional (#266)

📖 Documentation

🏡 Chore

✅ Tests

🎨 Styles

❤️ Contributors

v1.1.1

compare changes

🏡 Chore

  • Update dev dependencies (8fc7d96)

❤️ Contributors

  • Pooya Parsa (@pi0)

v1.1.0

compare changes

🚀 Enhancements

  • Support ignoreResponseError option (#221)
  • pkg: Add export conditions for runtime keys (#246)

🩹 Fixes

  • Pass empty object to headers initializer to prevent crash on chrome 49 (#235)
  • Export ResponseMap type to allow composition of ofetch (#232)
  • Fix issues with native node fetch (#245)
  • pkg: Add ./package.json subpath (253707a)
  • Deep merge fetch options (#243)

📖 Documentation

  • readme: Use _data rather than data for raw requests (#239)
  • Mention DELETE is no-retry be default (#241)

🏡 Chore

  • readme: Small improvements (65921a1)

🤖 CI

  • Enable tests against node 16, 18 and 20 (351fc80)

❤️ Contributors

v1.0.1

compare changes

🩹 Fixes

  • Improve error message for request errors (#199)

📖 Documentation

  • Fix small typos (#200)
  • Fix typo (#175)
  • Add agent option usage (#173)
  • Add note about http agent (#202)

📦 Build

  • Use standalone commonjs dist (#211)

🏡 Chore

🎨 Styles

❤️ Contributors

1.0.0 (2022-11-15)

⚠ BREAKING CHANGES

  • drop undici support

Features

0.4.21 (2022-11-03)

Features

  • add status and statusText to fetch errors (#152) (784a7c0)

Bug Fixes

  • only call error handler if status code is >= 400 (#153) (385f7fe)

0.4.20 (2022-10-17)

Bug Fixes

  • add backwards-compatible subpath declarations (#144) (3a48c21)
  • types: allow synchronous interceptors to be passed (#128) (46e8f3c)

0.4.19 (2022-09-19)

Features

  • support responseType: 'stream' as ReadableStream (#100) (5a19f73)

Bug Fixes

0.4.18 (2022-05-20)

Bug Fixes

0.4.17 (2022-05-11)

Features

0.4.16 (2022-04-29)

Bug Fixes

  • generalise application/json content types (#75) (adaa03b)

0.4.15 (2022-01-18)

Bug Fixes

  • use _data rather than data to store deserialized response (#49) (babb331)

0.4.14 (2021-12-22)

Bug Fixes

  • avoid calling fetch with globalOptions context (8ea2d2b)

0.4.13 (2021-12-21)

Features

  • $fetch.create support (d7fb8f6)
  • initial interceptor support (resolves #19) (1bf2dd9)

0.4.12 (2021-12-21)

Bug Fixes

0.4.11 (2021-12-17)

Features

  • return blob if content-type isn't text, svg, xml or json (#39) (1029b9e)

0.4.10 (2021-12-14)

Bug Fixes

  • avoid optional chaining (931d12d)

0.4.9 (2021-12-14)

Features

  • improve json body handling (4adb3bc), closes #36

0.4.8 (2021-11-22)

Bug Fixes

  • add accept header when using json payload (#30) (662145f)

0.4.7 (2021-11-18)

Bug Fixes

  • use application/json for array body (#29) (e794b1e)

0.4.6 (2021-11-10)

Bug Fixes

  • add check for using Error.captureStackTrace (#27) (0c55e1e)
  • remove baseurl append on retry (#25) (7e1b54d)

0.4.5 (2021-11-05)

Bug Fixes

  • improve error handling for non-user errors (6b965a5)

0.4.4 (2021-11-04)

Bug Fixes

0.4.3 (2021-11-04)

Features

  • experimental undici support (dfa0b55)
  • node: pick globalThis.fetch when available over node-fetch (54b779b)
  • node: support http agent with keepAlive (#22) (18a952a)
  • support retry and default to 1 (ec83366)

Bug Fixes

  • remove at raw from stack (82351a8)

0.4.2 (2021-10-22)

Features

  • cjs: provide fetch and $fetch.raw exports (529af1c)

0.4.1 (2021-10-22)

Bug Fixes

  • avoid optional chaining for sake of webpack4 (38a75fe)

0.4.0 (2021-10-22)

⚠ BREAKING CHANGES

  • upgrade to node-fetch 3.x

Features

  • upgrade to node-fetch 3.x (ec51edf)

0.3.2 (2021-10-22)

Features

  • allow for custom response parser with parseResponse (#16) (463ced6)

Bug Fixes

  • check for globalThis before fallback to shims (#20) (b5c0c3b)

0.3.1 (2021-08-26)

Bug Fixes

0.3.0 (2021-08-25)

⚠ BREAKING CHANGES

  • use export condition to automatically use node-fetch

Features

  • direct export fetch implementation (65b27dd)
  • use export condition to automatically use node-fetch (b81082b)

0.2.0 (2021-04-06)

⚠ BREAKING CHANGES

  • don't inline dependencies

Features

  • don't inline dependencies (cf3578b)

0.1.8 (2021-02-22)

Bug Fixes

  • pkg: add top level node.d.ts (dcc1358)

0.1.7 (2021-02-19)

Features

  • support automatic json body for post requests (#7) (97d0987)

0.1.6 (2021-01-12)

0.1.5 (2021-01-04)

Bug Fixes

  • pkg: use same export names for incompatible tools (7fc450a)

0.1.4 (2020-12-16)

Features

  • update ufo to 0.5 (reducing bundle size) (837707d)

0.1.3 (2020-12-16)

Bug Fixes

0.1.2 (2020-12-16)

Bug Fixes

0.1.1 (2020-12-12)

Bug Fixes

  • preserve params when using baseURL (c3a63e2)

0.0.7 (2020-12-12)

0.0.6 (2020-12-12)

Bug Fixes

  • pkg: fix top level named exports (0b51462)

0.0.5 (2020-12-12)

Bug Fixes

  • pkg: fix ./node in exports (c6b27b7)

0.0.4 (2020-12-12)

Features

0.0.3 (2020-12-12)

Features

  • bundle ufo and destr for easier bundler integration (8f5ba88)
  • support $fetch.raw and improve docs (f9f70a5)

0.0.2 (2020-12-09)

Bug Fixes

  • pkg: add top level dist (6da17ca)

0.0.1 (2020-12-09)

Features

  • universal + isomorphic builds (a873702)