Synchronous Fetch API for Node.js and Browser
sync-fetch is a JavaScript library that provides a synchronous wrapper around the standard Fetch API, enabling blocking network requests in environments where asynchronicity is not desired or feasible. Currently at version 0.6.0, it sees intermittent updates, with the last publish approximately four months ago, indicating an actively maintained but not rapidly evolving project. It internally leverages `node-fetch` for Node.js environments and `XMLHttpRequest` for browser contexts, adapting the underlying mechanism to provide a unified synchronous interface. Its primary differentiation is the synchronous execution, which, while useful for niche scenarios such as initial configuration loading or specific command-line utilities in Node.js, or within Web Workers in browsers to avoid blocking the main thread, generally carries significant performance and responsiveness implications due to its blocking nature. It is crucial to understand that using `sync-fetch` on the main thread of a browser or within the Node.js event loop will halt all other operations until the network request completes, making it generally unsuitable for interactive applications. The library explicitly outlines several limitations, particularly regarding body types like `Stream` or `Blob` and some advanced `fetch` options, which are inherent to synchronous request models.
Common errors
-
Cannot use Stream or Blob as request body
cause The synchronous nature of `sync-fetch` in Node.js prevents it from reading or serializing asynchronous data types like `Stream` or `Blob` for the request body.fixConvert `Stream` or `Blob` data into a synchronously readable format (e.g., `Buffer` or string) before passing it as the `body` option. -
Error [ERR_REQUIRE_ESM]: require() of ES Module ... not supported
cause This error occurs when attempting to `require()` an ECMAScript Module (ESM) in a CommonJS context. While `sync-fetch` provides a CommonJS `require` entry, its internal dependency `node-fetch` v3 is ESM-only. This error might indicate an incompatibility or misconfiguration if `sync-fetch`'s internal mechanisms fail to bridge the CJS/ESM gap correctly for its dependencies, or if you are trying to `import` `sync-fetch` directly in an ESM project where it only exposes CJS.fixFor Node.js, ensure you are using `const fetch = require('sync-fetch')`. If the error persists due to internal dependencies, verify your Node.js runtime environment (>=18 is required). If you are in an ESM project, and `sync-fetch` does not provide an ESM export, you might need to use dynamic `import()` or tools that bridge CJS and ESM, though this package's core design revolves around synchronous CJS for Node.js. -
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.
cause This is a browser console warning (or error in strict environments) indicating that you are using `sync-fetch` on the browser's main UI thread, which causes the page to become unresponsive during the network request.fixRefactor your code to use the standard, asynchronous `fetch` API for browser main thread operations. If synchronous behavior is absolutely required, move the `sync-fetch` call into a Web Worker to avoid blocking the UI thread.
Warnings
- breaking This package provides synchronous I/O. Using `sync-fetch` on the main thread of a browser will block the UI, making the page unresponsive. In Node.js, it will block the event loop, halting all other operations and significantly degrading application performance. It is generally suitable only for Web Workers or CLI tools where blocking is acceptable or desired.
- gotcha The Node.js implementation of `sync-fetch` has significant limitations on request body types. It does not support `Stream`, `Blob`, or `FormData` instances as input bodies because they cannot be read or serialized synchronously. Additionally, the non-spec `agent` option is not supported.
- gotcha When used in browser environments, `sync-fetch` relies on `XMLHttpRequest` and consequently supports only a limited set of `fetch` options (`method`, `body`, `headers`, `credentials`, `timeout`). Standard `fetch` features like `redirect`, `integrity`, or `cache` are often unavailable. CORS limitations apply and may be stricter for synchronous requests.
- gotcha While `sync-fetch` relies on `node-fetch` internally, `node-fetch` v3 is an ESM-only module. If you are working in a CommonJS Node.js project and face issues related to `require()` of ESM modules, it might stem from `sync-fetch`'s internal dependency resolution, even though `sync-fetch` itself exposes a CommonJS `require` interface.
Install
-
npm install sync-fetch -
yarn add sync-fetch -
pnpm add sync-fetch
Imports
- fetch
import fetch from 'sync-fetch'
const fetch = require('sync-fetch') - fetch (global)
<script src="https://unpkg.com/sync-fetch"></script> // 'fetch' is now globally available
- SyncResponse methods
const response = await fetch('http://example.com'); const data = await response.json();const response = fetch('http://example.com'); const data = response.json(); // or .text(), .buffer(), etc.
Quickstart
const fetch = require('sync-fetch');
const metadata = fetch('https://doi.org/10.7717/peerj-cs.214', {
headers: {
Accept: 'application/vnd.citationstyles.csl+json'
}
}).json();
console.log('DOI Metadata:', metadata);
// Example of synchronous text response
const textResponse = fetch('https://httpbin.org/get').text();
console.log('Plain Text Response (first 100 chars):', textResponse.substring(0, 100) + '...');
// Example with environment variable for API key (placeholder)
const apiKey = process.env.SOME_API_KEY ?? 'your_default_key';
// In a real scenario, avoid embedding keys directly. This is for demonstration.
const secureResponse = fetch(`https://api.example.com/data?key=${apiKey}`).json();
console.log('Secure Data (first 50 chars):', JSON.stringify(secureResponse).substring(0, 50) + '...');