@sekizlipenguen/connection
v0.2.6
Published
A lightweight and promise-based HTTP client for React Native, React, and Web applications. Supports fetch and XMLHttpRequest with advanced configuration options.
Maintainers
Readme
@sekizlipenguen/connection
Lightweight, promise-based HTTP client for React Native, React, and Web.
One small API. Two transports (fetch + XMLHttpRequest). Predictable timeouts, global headers, upload progress, and TypeScript types — without the weight of a full Axios clone.
npm install @sekizlipenguen/connection
# or
yarn add @sekizlipenguen/connectionimport connection from "@sekizlipenguen/connection";
const { data, statusCode } = await connection.get("https://api.example.com/users");
console.log(statusCode, data);Why this library?
| | |
|---|---|
| Tiny | ~8 KB source · ~3.6 KB minified · ~1.6 KB min+gzip · zero runtime dependencies |
| Dual transport | fetch by default; switch to xhr when you need upload progress |
| Predictable errors | Timeout always resolves as statusCode: 408 on both transports |
| Global defaults | Headers, timeout, and connect type via setConfig |
| RN + Web | Works in React Native 0.60+, browsers, and modern bundlers |
| Typed | First-class TypeScript definitions |
| Artifact | Size |
|----------|------|
| index.js (source) | ~8.1 KB |
| Minified (esbuild) | ~3.6 KB |
| Minified + gzip | ~1.6 KB |
| npm tarball | ~7 KB |
The published package ships readable source. Metro / Webpack / Vite minify it again in your app bundle, so end users typically pay the gzip-class cost — not the full 8 KB.
Features
get/post/put/patch/delete+ genericrequestfetch(default) orxhrper request or globally- Global header merge (
Authorization, etc.) - Auto
Content-Type: application/jsonfor plain object / array bodies - Timeout via
AbortController(fetch) andxhr.timeout(XHR) - Upload progress callback (XHR only)
- Safe JSON parsing (invalid JSON returns raw text instead of crashing)
- Optional debug logging
resetConfig()for tests / isolation
Quick start
import connection from "@sekizlipenguen/connection";
// Optional app-wide defaults
connection.setConfig({
timeout: 10000,
headers: {
Authorization: "Bearer your-token",
},
});
// GET
const users = await connection.get("https://api.example.com/users");
// POST
const created = await connection.post("https://api.example.com/users", {
name: "Ada",
role: "admin",
});
console.log(created.statusCode, created.data);async / await + error handling
try {
const response = await connection.get("https://api.example.com/profile");
console.log(response.data);
} catch (error) {
if (error.statusCode === 408) {
console.error("Request timed out");
} else if (error.statusCode === 0) {
console.error("Network disconnected");
} else {
console.error("HTTP error", error.statusCode, error.data);
}
}API
Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| get | (url, config?) | GET request |
| post | (url, data?, config?) | POST request |
| put | (url, data?, config?) | PUT request |
| patch | (url, data?, config?) | PATCH request |
| delete | (url, data?, config?) | DELETE request |
| request | (method, url, data?, config?) | Custom method |
| setConfig | (config) | Merge global defaults |
| resetConfig | () | Restore factory defaults |
| enableLogs | (boolean) | Toggle debug logs |
| areLogsEnabled | () | Read shared log flag (survives duplicate module copies) |
Response shape
Successful responses resolve to:
{
data: T; // parsed body
status: number; // HTTP status
statusCode: number; // same as status (alias)
ok?: boolean; // fetch only
headers?: Headers; // fetch only
request?: Response | XMLHttpRequest;
config?: Config;
}HTTP errors (4xx / 5xx) reject with the same shape (statusCode, data, …).
Timeouts reject with:
{ statusCode: 408, message: "Timeout occurred" }Network failures (XHR status 0) reject with:
{ statusCode: 0, message: "Network disconnected" }Configuration
Per-request config
await connection.get("https://api.example.com/slow", {
timeout: 15000,
headers: {
"X-Request-Id": "abc-123",
},
connectType: "fetch", // or "xhr"
});Config options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| connectType | 'fetch' \| 'xhr' | 'fetch' | Transport to use |
| headers | Record<string, string> | {} | Request headers (merged over globals) |
| timeout | number | 5000 | Timeout in milliseconds |
| progress | ((event) => void) \| null | null | Upload progress (XHR only) |
| files | boolean | false | Set true to skip JSON.stringify (FormData / binary) |
| logEnabled | boolean | false | Can also be set via setConfig / enableLogs |
| async | boolean | true | XHR open(..., async) flag |
| method | string | — | Set by API helpers / request() (also present on response config) |
Global configuration
setConfig merges into process-wide defaults. Headers are merged (not replaced wholesale), so you can set Authorization once and add more headers later.
connection.setConfig({
timeout: 10000,
connectType: "fetch",
headers: {
Authorization: "Bearer token",
Accept: "application/json",
},
});
// Later — keeps Authorization, adds another header
connection.setConfig({
headers: {
"X-App-Version": "1.2.0",
},
});
// Restore defaults (useful in tests)
connection.resetConfig();Examples
Custom headers & timeout
await connection.get("https://api.example.com/data", {
headers: {
Authorization: "Bearer token",
},
timeout: 10000,
});PUT / PATCH / DELETE
await connection.put("https://api.example.com/users/1", { name: "Grace" });
await connection.patch("https://api.example.com/users/1", { role: "editor" });
await connection.delete("https://api.example.com/users/1");File upload with progress (XHR)
Use connectType: "xhr" and files: true so the body is not JSON-stringified.
const formData = new FormData();
formData.append("file", file);
await connection.post("https://api.example.com/upload", formData, {
connectType: "xhr",
files: true, // do not JSON.stringify the body
progress: (event) => {
if (!event.lengthComputable) return;
const percent = Math.round((event.loaded * 100) / event.total);
console.log(`Upload: ${percent}%`);
},
});Force XHR globally
connection.setConfig({ connectType: "xhr" });Debug logging
connection.enableLogs(true);
connection.areLogsEnabled(); // true
// [Connection Log]: Fetch Connect Start: ...
connection.enableLogs(false);
connection.areLogsEnabled(); // false
// or
connection.setConfig({ logEnabled: true });Handy in React Native when you want quick visibility into request lifecycle without a proxy.
Note: log flag is shared via
globalThis, so if Metro loads the package twice (app + nested dependency) oneenableLogs(false)still silences all copies.
TypeScript
import connection, {
Config,
ReturnTypeConfig,
ConnectionError,
} from "@sekizlipenguen/connection";
interface User {
id: number;
name: string;
}
const config: Config = {
timeout: 10000,
headers: {
Authorization: "Bearer token",
},
};
async function loadUser(id: number) {
try {
const response: ReturnTypeConfig<User> = await connection.get(
`https://api.example.com/users/${id}`,
config,
);
return response.data;
} catch (error) {
const err = error as ConnectionError;
console.error(err.statusCode, err.message, err.data);
throw err;
}
}fetch vs xhr
| | fetch (default) | xhr |
|---|---|---|
| Best for | Everyday API calls | Uploads with progress |
| Timeout | AbortController → 408 | xhr.timeout → 408 |
| Progress | — | config.progress |
| Response headers | Available on result | Via request.getResponseHeader |
Pick per call with connectType, or set a global default with setConfig.
React Native notes
- Works with RN networking out of the box (modern RN includes
fetch+AbortController). - Prefer
fetchfor normal REST traffic. - Use
xhrwhen you need upload progress. - Toggle
enableLogs(true)during development to inspect request flow.
Testing this package
npm install
npm test # static integrity + e2e
npm run test:e2e # network e2e onlynpm test first cross-checks package.json ↔ index.js ↔ index.d.ts ↔ README.md, then runs the e2e suite (local HTTP server + public smoke endpoint) for both fetch and xhr.
What gets published to npm
Git can keep tests and tooling. The npm tarball is limited by the files whitelist to:
index.jsindex.d.tsLICENSEREADME.mdpackage.json(always included by npm)
e2e/, node_modules/, lockfiles, and editor junk are not published. prepack runs npm test before npm pack / npm publish.
License
MIT © SekizliPenguen — see LICENSE.
Repository: github.com/sekizlipenguen/SPConnection
