Skip to content

dev-dami/kiattp

Repository files navigation

kiattp

npm version bundle size CI license node downloads

A zero-dependency, fast, lightweight HTTP client. 4× faster than Axios, ~3.7KB gzipped, zero dependencies.

npm install kiattp

No postinstall scripts · No dependency tree to audit · Zero runtime deps


Quick Start

import { get, post, createInstance } from 'kiattp';

const users = await get<User[]>('https://api.example.com/users');
const user = await post<User>('https://api.example.com/users', { body: { name: 'Alice' } });

const api = createInstance({
  baseURL: 'https://api.example.com',
  headers: { Authorization: 'Bearer token' },
});

const data = await api.get<User[]>('/users');

Axios Compatibility

Drop-in replacement via kiattp/axios — no code changes required:

import { axios } from 'kiattp/axios';

const res = await axios.get('https://api.example.com/users');
const api = axios.create({ baseURL: 'https://api.example.com' });

// CancelToken, isCancel, isAxiosError, all, spread — all supported
const source = axios.CancelToken.source();
axios.get('/slow', { cancelToken: source.token });
source.cancel('Cancelled');

See full Axios compat reference below.

Subpath Exports

Import only what you need to keep your bundle minimal:

// Node.js http adapter (no fetch)
import { httpAdapter } from 'kiattp/http';

// Individual plugins
import { retry_plugin } from 'kiattp/plugins/retry';
import { logger_plugin } from 'kiattp/plugins/logger';
import { timeout_plugin } from 'kiattp/plugins/timeout';

// Full entry (re-exports everything)
import { get, createInstance } from 'kiattp';

// Axios compatibility layer
import { axios } from 'kiattp/axios';

Plugins

import { createInstance, retry_plugin, logger_plugin, timeout_plugin } from 'kiattp';

const api = createInstance({ baseURL: 'https://api.example.com' });

api.use(retry_plugin({ maxRetries: 3, backoff: 'exponential', jitter: true }));
api.use(logger_plugin({ level: 'info' }));
api.use(timeout_plugin({ timeout: 10_000 }));

Interceptors

// Request interceptors
api.interceptors.request.use((config) => {
  config.headers['authorization'] = 'Bearer ' + getToken();
  return config;
});

// Response interceptors
api.interceptors.response.use((res) => {
  console.log(`${res.status} ${res.config.url}`);
  return res;
});

// Error interceptors
api.interceptors.response.use(
  (res) => res,
  (error) => {
    console.error(`Request failed: ${error.message}`);
    return error;
  },
);

Transforms

// Transform request before serialization
api.interceptors.request.use((config) => {
  config.headers['x-request-id'] = crypto.randomUUID();
  return config;
});

// Transform response after parsing
api.interceptors.response.use((res) => {
  res.data = sanitize(res.data);
  return res;
});

Progress & Binary

// Upload progress
await post('/upload', {
  body: formData,
  onUploadProgress: ({ loaded, total }) => console.log(`${loaded}/${total}`),
});

// Download progress
await get('/file.pdf', {
  responseType: 'blob',
  onDownloadProgress: ({ loaded, total }) => console.log(`${loaded}/${total}`),
});

// Binary responses
const blob   = await get<Blob>('/file.pdf',   { responseType: 'blob' });
const buffer = await get<ArrayBuffer>('/data', { responseType: 'arraybuffer' });
const stream = await get<ReadableStream>('/large', { responseType: 'stream' });

Error Handling

try {
  await get('/users');
} catch (err) {
  if (err.isAxiosError) {
    console.error(`HTTP ${err.status}: ${err.statusText}`);
    console.error(err.response?.data);
  }
}

// Custom status validation
await get('/maybe-found', { validateStatus: (s) => s < 500 });

Per-Instance Adapter

// Force Node.js http adapter (supports proxy, maxRedirects)
const api = createInstance({ adapter: 'http' });

// Force fetch adapter
const browser = createInstance({ adapter: 'fetch' });

API Reference

Methods

Function Description
get(url, config?) GET request
post(url, config?) POST request
put(url, config?) PUT request
patch(url, config?) PATCH request
del(url, config?) DELETE request
head / options / request Standard HTTP methods
createInstance(defaults?) Scoped client with preset defaults

Config

Option Type Description
baseURL string Prepended to relative paths. Trailing/leading slashes handled automatically.
params `Record<string, string number
paramsSerializer (params: Record<string, unknown>) => string Custom query string builder
headers Record<string, string> Deep-merged with instance defaults; call-time wins
body `string FormData
timeout number Milliseconds
signal AbortSignal Cancellation
responseType `'json' 'text'
validateStatus (status: number) => boolean Default: 200–299
adapter `'fetch' 'http'`
credentials RequestCredentials Browser only — include, same-origin, omit
maxContentLength number Reject responses larger than this (bytes)
decompress boolean Auto-decompress gzip/deflate/br (Node.js http adapter)
xsrfCookieName string CSRF cookie name for XSRF header injection (browser only)
xsrfHeaderName string CSRF header name (default: X-XSRF-TOKEN)
transformRequest TransformFn[] Functions run before body serialization
transformResponse TransformFn[] Functions run after response parsing
onUploadProgress (e: ProgressEvent) => void { loaded, total?, bytes }
onDownloadProgress (e: ProgressEvent) => void { loaded, total?, bytes }
maxRedirects number Node.js http adapter only
proxy ProxyConfig { host, port, protocol?, auth? } — http adapter only

Response Shape

interface Response<T> {
  data: T;
  status: number;
  statusText: string;
  headers: Record<string, string>;
  config: Config;
}

Axios Compat Reference

Method Notes
axios.get/post/put/patch/delete/head/options/request Full parity
axios.create(defaults?) Maps to createInstance
axios.all(promises) Promise.all alias
axios.spread(fn) Spread array args to callback
axios.CancelToken.source() Maps to AbortController internally
axios.isCancel(err) Cancellation type guard
axios.isAxiosError(err) HTTP error type guard

Benchmarks

See BENCHMARK.md — MSW mock server, Node.js 18+.

ops/sec Mean p99 Size (gzipped)
kiattp ~4,000 0.25ms 0.80ms ~3.7KB
axios ~940 1.07ms 4.83ms ~14KB
native fetch ~6,100 0.16ms 0.32ms 0KB
  • kiattp is ~4× faster than Axios and ~1.5× slower than native fetch
  • The ~0.09ms overhead vs fetch pays for config normalization, interceptors, and error handling

License

MIT

About

A zero-dependency, fast, lightweight HTTP client library for Node.js and browsers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors