npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@camozdevelopment/voltfetch

v0.2.0

Published

A secure, lightweight, edge-ready fetch client for TypeScript—retries, timeouts, caching, axios-friendly API, zero runtime dependencies.

Readme

VoltFetch

A secure, lightweight, edge-ready HTTP client for TypeScript—built on fetch, with axios-friendly ergonomics and zero runtime dependencies.

npm install @camozdevelopment/voltfetch

Requires Node.js ≥ 18 (or any environment with global fetch). ESM-only.


Why VoltFetch over Axios?

| | Axios | VoltFetch | |---|-----------|---------------| | Transport | XHR / http adapters, large surface | Native fetch everywhere | | Bundle / deps | Multiple dependencies | Zero runtime dependencies | | Edge & Workers | Often awkward or extra config | Same code on Node, browser, Bun, CF Workers, Vercel Edge | | Security | DIY for SSRF-style controls | allowedDomains, blockedDomains, blockPrivateIPs, redirect auth stripping, maxResponseSize | | Retries / timeout | Optional plugins or manual | Built-in retries with backoff + Retry-After, timeouts without timer leaks | | Caching | External | Optional in-memory GET cache + in-flight dedupe | | Typing | Mature | First-class generics + stable VoltFetchError codes | | Familiar API | axios.create, interceptors | createClient, interceptors, params / data, paramsSerializer |

Axios is excellent for many stacks. VoltFetch is for teams that want fetch semantics, smaller installs, edge-native behavior, and explicit outbound URL controls without maintaining a parallel HTTP stack.


Quick start

import { createClient, VoltFetchError } from "@camozdevelopment/voltfetch";

const api = createClient({
  baseURL: "https://api.example.com",
  timeout: 5000,
  retries: 2,
  retryDelay: 300,
  headers: { Accept: "application/json" },
});

const user = await api.get<User>("/users/me");

await api.post("/posts", { title: "Hello" });

Axios-style options

const api = createClient({
  baseURL: "https://api.example.com",
  paramsSerializer: (q) => new URLSearchParams(q as Record<string, string>).toString(),
  jsonStripUndefined: true,
  interceptors: {
    request: [(ctx) => { /* mutate ctx.init.headers */ }],
  },
});

// params merges after query; same keys → params wins
await api.get("/search", { query: { q: "a" }, params: { page: 2 } });

// data is an alias for body
await api.request({ url: "/items", method: "POST", data: { name: "x" } });

Custom fetch (tests, proxies, runtimes)

const api = createClient({
  baseURL: "https://api.example.com",
  fetch: myFetchImplementation,
});

Build a URL without requesting

import { buildRequestUrl } from "@camozdevelopment/voltfetch";

const href = buildRequestUrl("https://api.example.com", "/users", {
  query: { role: "admin" },
});

Features

| Feature | Notes | |--------|--------| | Methods | get, post, put, patch, delete, head, options, request | | Body / query | data, params, paramsSerializer, jsonStripUndefined | | Parsing | parseAs: json | text | blob | arrayBuffer | formData | raw | | Hooks & interceptors | hooks + interceptors (axios-like naming) | | Timeouts | AbortController; cleaned up on completion | | Retries | Extra attempts after the first; backoff + jitter; Retry-After | | Cache / dedupe | Optional memory cache + in-flight GET coalescing | | Security | Domain allow/block lists, literal private IP block, redirect hardening, size limits | | fetch injection | Client-level and per-request override |

Upload progress is not faked: the Fetch standard does not expose it cross-runtime. Use ReadableStream bodies where supported.


Configuration (summary)

| Option | Purpose | |--------|---------| | baseURL | Required for relative URLs | | timeout | Ms; 0 = off | | retries | Extra attempts (not including the first) | | retryDelay / retryOn | Backoff + custom retry policy (number[] or function) | | cache / cacheTTL / dedupe | GET caching and deduplication | | allowedDomains / blockedDomains / blockPrivateIPs | Outbound URL policy | | maxResponseSize / maxRedirects / followRedirects | Safety limits | | throwOnHTTPError / validateStatus | HTTP error behavior | | fetch | Custom fetch implementation | | interceptors | { request, response, error } arrays (run before hooks) |

Full tables and hook examples: see Documentation site (npm run site:dev) or source src/types.ts.


Errors

VoltFetchError exposes code (TIMEOUT, NETWORK_ERROR, SECURITY_ERROR, HTTP_ERROR, ABORT, RESPONSE_SIZE_EXCEEDED, REDIRECT_ERROR, UNKNOWN), status, data, response, and flags like isHTTPError. Use VoltFetchError.fromUnknown(err) to normalize unknown errors.


Security

See SECURITY.md for reporting and scope. VoltFetch does not resolve DNS for outbound URLs; literal-IP and host-pattern checks complement—but do not replace—egress controls for high-risk SSRF scenarios.


Website

npm run site:dev      # local dev
npm run site:build    # → website/dist/

Exports

import voltfetch, {
  createClient,
  VoltFetchError,
  buildRequestUrl,
  mergeQueryLayers,
  stringifyQuery,
  stripUndefinedDeep,
  createMemoryCache,
  MemoryCacheStore,
  buildAuthHeaders,
  createAuthHeaders,
  mergeHooks,
  defaultRetryOn,
  parseRetryAfter,
  resolveRetryDecision,
  assertUrlSafe,
  isPrivateOrLocalHost,
} from "@camozdevelopment/voltfetch";

Contributing & changelog

License

MIT — see LICENSE.