universal-api-errors
One consistent, fully-typed error object — no matter which HTTP client or backend framework sent it
What It Is
An open-source TypeScript library that normalizes API errors from any HTTP client — Axios, fetch, and more — into one consistent, fully-typed error object. Published as 5 npm packages with a live docs site and interactive playground.
The Problem It Solves
Every frontend/backend project ends up re-implementing the same brittle error-parsing logic — scattered `if (error.response?.status === 401)` checks that break the moment a different backend spells "unauthorized" differently. Every backend framework shapes its errors differently:
Laravel
{ "message": "Invalid Password" }NestJS
{ "statusCode": 401, "message": "Token Expired", "error": "Unauthorized" }FastAPI
{ "detail": [{ "loc": ["body", "email"], "msg": "field required" }] }How It Works
universal-api-errors normalizes all of these — from Axios, fetch, or virtually any error shape — into one predictable UniversalError:
import { parseAxiosError } from '@harshilrajput/universal-api-errors-axios';
try {
await axios.get('/api/user');
} catch (err) {
const error = parseAxiosError(err);
error.message; // "Token Expired"
error.status; // 401
error.type; // "Unauthorized"
error.isUnauthorized; // true
error.retryable; // false
error.validation; // { email: ["Already exists"] } — normalized field errors
}Key Features
- Zero runtime dependencies in core — achieved via duck-typing rather than importing Axios/fetch types, so the core package works standalone with any HTTP client
- Strict TypeScript — exactOptionalPropertyTypes, noUncheckedIndexedAccess, zero any
- 91 tests, CI-verified on Node 22 and 24 via GitHub Actions
- Dual ESM/CJS builds with generated .d.ts via tsup
- Unified error-classification logic — every adapter agrees on what counts as a network error by construction, not by convention
- Published and real — live on npm under the @harshilrajput scope, MIT licensed, versioned with Changesets
- A working, live playground — runs the actual published package in the browser against pasted JSON, not a mocked demo
How It's Built
- A pnpm monorepo of 5 independently versioned, independently published npm packages
- Core package recognizes error shapes via duck-typing — no imports of Axios/fetch types needed, so it works standalone with any HTTP client
- Discovered and fixed a real ES-module `export *` collision that would have silently dropped exports
- Fixed a build-tool bug where esbuild strips "use client" directives, via a post-build patch step
- Dual ESM/CJS builds with generated .d.ts via tsup
- 91 tests, CI-verified on Node 22 and 24 via GitHub Actions
- MIT licensed, versioned and released with Changesets
Packages
@harshilrajput/universal-api-errors-core
Zero-runtime-dependency parser + the UniversalError model. Recognizes error shapes via duck-typing (no imports of Axios/etc. needed).
@harshilrajput/universal-api-errors-axios
Thin Axios-specific adapter
@harshilrajput/universal-api-errors-fetch
Thin fetch-specific adapter (async, since reading a Response body requires it)
@harshilrajput/universal-api-errors-react-query
useApiError() hook + createRetry() for TanStack React Query
@harshilrajput/universal-api-errors
Batteries-included bundle (core + Axios + fetch in one install)
Documentation Site
A full documentation website built with Next.js 16, Tailwind CSS v4, Fumadocs, deployed independently from the library itself.
A live interactive playground that runs the actual published package in the browser against pasted JSON — not a mocked demo
Full documentation for all 5 packages and their APIs
Built with Fumadocs on Next.js 16
At a glance
- License
- MIT
- Packages
- 5