CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ofetch

Universal HTTP fetch library with intelligent parsing, error handling, retry logic, and cross-environment compatibility

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

configuration.mddocs/

Configuration and Instance Management

Create customized fetch instances with default options, base URLs, platform-specific settings, and advanced configuration for different environments and use cases.

Capabilities

Fetch Instance Creation

Create customized fetch instances with default options that apply to all requests made with that instance.

/**
 * Create a customized fetch instance with default options
 * @param defaults - Default fetch options to merge with each request
 * @param globalOptions - Global configuration for fetch implementation
 * @returns New $Fetch instance with configured defaults
 */
function create(
  defaults?: FetchOptions,
  globalOptions?: CreateFetchOptions
): $Fetch;

interface CreateFetchOptions {
  defaults?: FetchOptions;
  fetch?: Fetch;
  Headers?: typeof Headers;
  AbortController?: typeof AbortController;
}

Usage Examples:

import { ofetch } from "ofetch";

// Basic API client with base URL
const api = ofetch.create({
  baseURL: "https://api.example.com"
});

// Full configuration with authentication and timeouts
const authenticatedApi = ofetch.create({
  baseURL: "https://api.example.com",
  headers: {
    "Authorization": "Bearer token123",
    "Content-Type": "application/json",
    "User-Agent": "MyApp/1.0"
  },
  timeout: 10000,
  retry: 3,
  retryDelay: 1000
});

// Environment-specific configuration
const api = ofetch.create({
  baseURL: process.env.API_BASE_URL,
  headers: {
    "X-API-Key": process.env.API_KEY
  }
});

Factory Function

Lower-level factory function for creating fetch instances with custom fetch implementations and global options.

/**
 * Factory function to create fetch instances with custom implementations
 * @param globalOptions - Global configuration including custom fetch implementation
 * @returns New $Fetch instance with specified configuration
 */
function createFetch(globalOptions?: CreateFetchOptions): $Fetch;

Usage Examples:

import { createFetch } from "ofetch";

// Custom fetch instance with specific global options
const customFetch = createFetch({
  defaults: {
    baseURL: "https://internal.api.com",
    timeout: 5000
  },
  fetch: globalThis.fetch,
  Headers: globalThis.Headers,
  AbortController: globalThis.AbortController
});

// Use with custom fetch implementation
const proxyFetch = createFetch({
  fetch: (input, init) => {
    console.log("Proxying request:", input);
    return globalThis.fetch(input, init);
  }
});

Node.js Specific Configuration

Node.js optimized fetch creation with keep-alive support and HTTP agent configuration. The main ofetch package automatically detects Node.js environment and uses optimizations, but explicit Node.js configuration is available.

/**
 * Creates Node.js-specific fetch with conditional keep-alive support
 * Reads FETCH_KEEP_ALIVE environment variable to enable persistent connections
 * @returns Fetch function with Node.js optimizations and optional keep-alive
 */
function createNodeFetch(): typeof globalThis.fetch;

Keep-Alive Support:

When FETCH_KEEP_ALIVE environment variable is set to "true", Node.js HTTP and HTTPS agents are created with keepAlive: true to reuse connections across requests.

Usage Examples:

import { createNodeFetch } from "ofetch/node";

// Enable keep-alive via environment variable
process.env.FETCH_KEEP_ALIVE = "true";
const fetch = createNodeFetch();

// Without keep-alive (default behavior)
process.env.FETCH_KEEP_ALIVE = "false";
const standardFetch = createNodeFetch();

// Use in custom instance
import { createFetch } from "ofetch";
const nodeFetch = createFetch({
  fetch: createNodeFetch(),
  defaults: { timeout: 10000 }
});

// Automatic Node.js detection (recommended)
import { ofetch } from "ofetch"; // Uses Node.js optimizations automatically in Node.js
const data = await ofetch("https://api.example.com/data");

Request Options Configuration

Comprehensive options for configuring individual requests and default behaviors.

interface FetchOptions<R extends ResponseType = ResponseType, T = any>
  extends Omit<RequestInit, "body">, FetchHooks<T, R> {
  // URL Configuration
  baseURL?: string;
  query?: Record<string, any>;
  params?: Record<string, any>; // Alias for query

  // Request Body
  body?: RequestInit["body"] | Record<string, any>;

  // Response Handling
  responseType?: R;
  parseResponse?: (responseText: string) => any;
  ignoreResponseError?: boolean;

  // Timeout and Retry
  timeout?: number;
  retry?: number | false;
  retryDelay?: number | ((context: FetchContext<T, R>) => number);
  retryStatusCodes?: number[];

  // Streaming
  duplex?: "half" | undefined;

  // Node.js Specific (>= 18)
  dispatcher?: InstanceType<typeof import("undici").Dispatcher>;
  
  // Node.js Specific (< 18)
  agent?: unknown;
}

Usage Examples:

import { ofetch } from "ofetch";

// URL and query configuration
const data = await ofetch("https://api.example.com/search", {
  baseURL: "https://api.example.com", // Would result in https://api.example.com/search
  query: { q: "typescript", limit: 10 }
});

// Response configuration
const text = await ofetch("https://api.example.com/document", {
  responseType: "text",
  parseResponse: (text) => text.toUpperCase()
});

// Timeout and retry configuration
const data = await ofetch("https://unreliable-api.com/data", {
  timeout: 5000,
  retry: 3,
  retryDelay: (context) => Math.min(1000 * Math.pow(2, context.options.retry || 0), 10000),
  retryStatusCodes: [408, 429, 500, 502, 503, 504]
});

// Error handling configuration
const response = await ofetch("https://api.example.com/might-fail", {
  ignoreResponseError: true // Won't throw on 4xx/5xx status codes
});

Headers Configuration

Configure request headers with proper merging and override behavior.

interface ResolvedFetchOptions<R extends ResponseType = ResponseType, T = any> 
  extends FetchOptions<R, T> {
  headers: Headers;
}

Usage Examples:

import { ofetch } from "ofetch";

// Static headers
const api = ofetch.create({
  headers: {
    "Authorization": "Bearer token",
    "Content-Type": "application/json"
  }
});

// Dynamic headers
const api = ofetch.create({
  async onRequest({ options }) {
    const token = await getAuthToken();
    options.headers.set("Authorization", `Bearer ${token}`);
  }
});

// Per-request header override
const data = await api("/admin/users", {
  headers: {
    "X-Admin": "true" // Adds to existing headers
  }
});

Conditional Exports and Environment Detection

ofetch uses conditional exports to automatically provide the best implementation for each environment:

  • Browser/Universal: Uses globalThis.fetch with polyfill fallback
  • Node.js: Automatically uses node-fetch-native with conditional keep-alive support
  • Edge Runtime/Workers: Uses native globalThis.fetch

Package Exports Structure:

{
  "exports": {
    ".": {
      "node": "./dist/node.mjs",
      "import": "./dist/index.mjs",
      "require": "./dist/node.cjs"
    },
    "./node": {
      "import": "./dist/node.mjs",
      "require": "./dist/node.cjs"
    }
  }
}

Advanced Node.js Configuration

Advanced Node.js specific configuration including HTTP agents, proxies, and custom dispatchers.

Usage Examples:

// HTTP Agent configuration (Node.js < 18)
import { HttpsProxyAgent } from "https-proxy-agent";
import { ofetch } from "ofetch";

const data = await ofetch("https://api.example.com/data", {
  agent: new HttpsProxyAgent("http://proxy.example.com:8080")
});

// Undici Dispatcher (Node.js >= 18)
import { ProxyAgent } from "undici";
import { ofetch } from "ofetch";

const proxyAgent = new ProxyAgent("http://proxy.example.com:8080");
const data = await ofetch("https://api.example.com/data", {
  dispatcher: proxyAgent
});

// Keep-alive configuration
process.env.FETCH_KEEP_ALIVE = "true";
import { ofetch } from "ofetch/node";
// All requests will use keep-alive connections

Global Configuration Types

interface CreateFetchOptions {
  defaults?: FetchOptions;
  fetch?: Fetch;
  Headers?: typeof Headers;
  AbortController?: typeof AbortController;
}

type GlobalOptions = Pick<FetchOptions, "timeout" | "retry" | "retryDelay">;

Install with Tessl CLI

npx tessl i tessl/npm-ofetch

docs

configuration.md

core-operations.md

error-handling.md

index.md

interceptors.md

utilities.md

tile.json