Why parcely?
parcely is a fetch-based HTTP client for TypeScript and JavaScript. It gives you the ergonomic, batteries-included API you know from axios -- createClient, interceptors, typed responses, upload progress -- while fixing the security and architectural issues that have produced axios CVEs over the past several years.
Design goals
- Zero runtime dependencies. Uses
globalThis.fetcheverywhere. On Node 20+, the built-inundicimodule is imported only when you explicitly set TLS overrides. - Secure by default. 13 defense rows (SSRF, redirect header stripping, CRLF injection, prototype-pollution-safe merging, and more) are enabled out of the box. See the Security defaults page.
- Tree-shakeable. Named exports only,
sideEffects: false, conditional dynamic import for TLS. Ship only what you use. - Universal runtime. Targets modern browsers, Node 20+, Bun, and Deno.
- Validator extension point. Opt-in runtime response validation via Standard Schema (Zod, Valibot, ArkType) or any
(input) => Tfunction. No validator runtime dependency. - Monorepo from day one. Core stays small. Companion packages handle common patterns:
@parcely/auth-token(bearer/refresh),@parcely/auth-redirect(browser login redirect),@parcely/retry(exponential backoff). Further slots (react, upload-node) are in development or reserved.
What it looks like
import { createClient } from '@parcely/core'
const http = createClient({
baseURL: 'https://api.example.com',
headers: { Accept: 'application/json' },
timeout: 5000,
})
const { data, status, headers } = await http.get('/users/me')
Coming from axios?
The API surface is intentionally familiar. The Migration guide has tabbed side-by-side snippets for every common pattern and a full feature-mapping table.