Popsicle HTTP Client
Popsicle is an advanced HTTP client library designed for both Node.js and browser environments, currently stable at version 12.1.2. It provides a fetch-like API, built upon the `Servie` request and response interfaces, offering a universal solution without requiring environment-specific configuration by default. Releases typically involve patch updates for bug fixes and dependency management, with major versions introducing significant architectural changes, such as the `Servie 4` migration in v12.0.0. Key differentiators include its modular middleware architecture, which allows for extensive customization, and its optimized bundles for different environments. Node.js environments benefit from built-in features like User-Agent handling, content encoding decoding, redirect following, and an in-memory cookie cache, while browser builds are lighter, focusing solely on the `XMLHttpRequest` transport layer. This design allows developers to compose functionality and create highly tailored HTTP clients.
Common errors
-
Error: EUNAVAILABLE: Unable to connect to the remote URL
cause The HTTP client failed to establish a connection to the target server, often due to network issues, incorrect hostname, or the server being offline.fixVerify network connectivity, confirm the URL is correct and accessible, and ensure the target server is running and listening on the specified port. -
TypeError: Invalid URL
cause The URL provided to the `fetch` function is syntactically incorrect or malformed, preventing the request from being initiated.fixDouble-check the URL string passed to `fetch` for proper formatting, including the protocol (e.g., `http://` or `https://`), domain name, and path segments. -
RangeError: EMAXREDIRECTS: Maximum number of redirects exceeded
cause The request followed too many HTTP redirects (default limit is typically 20), indicating a potential redirect loop or an overly long redirect chain on the server side (Node.js only).fixInspect the URL and server configuration for redirect loops. If legitimate, you might be able to configure a higher redirect limit, though this is often a symptom of misconfiguration. -
TypeError: fetch is not a function
cause This typically occurs when attempting to use `fetch` with CommonJS `require` syntax without correctly destructuring the named export, or incorrectly assuming it's a default export.fixFor ESM, use `import { fetch } from 'popsicle';`. For CommonJS, use `const { fetch } = require('popsicle');`.
Warnings
- breaking Version 12.0.0 introduced significant breaking changes by migrating to `Servie 4` interfaces and refactoring middleware. The `popsicle` package now primarily provides a `fetch`-like entry point, with most advanced middleware functionality extracted into separate reusable packages. Code relying on older middleware patterns or `Servie 3` interfaces will require updates.
- gotcha The default universal entry point (`popsicle`) requires DOM types in TypeScript projects, which can cause issues in pure Node.js environments if not configured correctly. This is due to its browser compatibility. To avoid this, explicit environment-specific imports are recommended.
- gotcha A vulnerability in `popsicle-cookie-jar` (which `popsicle` uses in Node.js) was identified that could affect custom setups, particularly in versions prior to 12.1.1. This could lead to unexpected cookie handling or potential security issues.
- gotcha When performing non-trivial HTTP requests (e.g., scraping, interacting with public APIs), it is crucial to override the default `User-Agent` and respect `robots.txt` to avoid being blocked or violating server policies.
- breaking Middleware functionality underwent a significant architectural change in version 12.0.0. The core `popsicle` package now serves more as an example of middleware composition, with advanced functionalities like user-agent setting, content encoding, redirects, and cookie handling moved to independent `popsicle-*` packages. Existing custom middleware or configurations might break.
Install
-
npm install popsicle -
yarn add popsicle -
pnpm add popsicle
Imports
- fetch
import fetch from 'popsicle';
import { fetch } from 'popsicle'; - AbortController
const AbortController = require('popsicle').AbortController;import { AbortController } from 'popsicle'; - Request, Response, Headers
const Request = require('popsicle').Request;import { Request, Response, Headers } from 'popsicle';
Quickstart
import { fetch, AbortController } from "popsicle";
const controller = new AbortController();
const signal = controller.signal;
// Simulate aborting the request after 500ms
setTimeout(() => {
console.log('Aborting request...');
controller.abort();
}, 500);
async function makeRequest() {
try {
// Replace with a valid API endpoint for testing
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1", { signal });
if (!res.ok) {
throw new Error(`HTTP error! Status: ${res.status}`);
}
const data = await res.json();
console.log("Response data:", data);
} catch (error: any) {
if (signal.aborted) {
console.log(`Request was aborted: ${error.name}`);
} else {
console.error(`Request failed unexpectedly: ${error.message}`);
}
}
}
makeRequest();