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

apex-fetch

v0.1.1

Published

Fast, stable, and configurable fetch layer built on top of native fetch.

Readme

APEX Fetch


[!IMPORTANT] ⚙️ APEX tetap menggunakan mesin fetch native. Library ini tidak mencoba mengganti fondasi runtime, tetapi memperkuat konfigurasi, timeout, retry, hooks, parsing response, dan error handling supaya lebih nyaman dipakai di project nyata.

[!WARNING] 🚫 Paket ini menggunakan lisensi UNLICENSED / All Rights Reserved. Penggunaan, modifikasi, redistribusi, atau pembuatan turunan tanpa izin tertulis dari pemilik hak cipta tidak diperbolehkan.

[!TIP] 🧠 Jika Anda suka kesederhanaan fetch, tetapi tidak ingin terus-menerus menulis ulang logic baseURL, timeout, retry, headers, dan error mapping, APEX dibuat untuk kebutuhan itu.

Daftar Isi


Visi Produk

🚀 APEX dirancang sebagai request layer yang terasa ringan saat dipakai, tetapi kuat saat dibutuhkan.

Nama APEX mewakili karakter produk yang ingin dibangun:

  • ⚡ Fast
  • 🛡️ Stable
  • 🎯 Productive
  • 😌 Comfortable
  • 🎯 Precise
  • 🧵 Smooth
  • 🧩 Highly configurable
  • 🌱 Beginner-friendly

APEX ditujukan untuk developer yang ingin tetap memakai fetch native, tetapi membutuhkan lapisan yang lebih rapi untuk:

  • pengelolaan baseURL
  • request config yang konsisten
  • auto JSON serialization
  • response parsing
  • retry policy
  • timeout dan abort handling
  • hook lifecycle
  • error contract yang seragam

Dengan kata lain, APEX tidak mengejar abstraksi berlebihan. APEX mengejar request flow yang konsisten, mudah dipahami, dan mudah ditingkatkan saat aplikasi mulai membesar.

Prinsip Desain

🧭 Berikut prinsip desain yang menjadi pondasi APEX:

| Prinsip | Penjelasan | | ----------------- | --------------------------------------------------------------------------------------------------- | | Native-first | APEX dibangun di atas fetch, jadi perilaku dasarnya tetap familiar bagi developer web modern. | | Predictable | Request, response, dan error memiliki kontrak yang konsisten supaya lebih mudah di-debug. | | Composable | Instance bisa diperluas lewat extend() tanpa perlu menyalin konfigurasi manual berulang kali. | | Safe defaults | Timeout, retry config, parsing, dan HTTP assertion berjalan dengan default yang masuk akal. | | Readable DX | API publik dirancang supaya tetap mudah dipakai oleh developer baru maupun tim yang sedang scaling. |


Mengapa APEX

| Kebutuhan | Native fetch | APEX | | ------------------------- | -------------- | ----------- | | Request sederhana | Baik | Baik | | Base URL global | Manual | Built-in | | Retry | Manual | Built-in | | Timeout | Manual | Built-in | | Hook request/response | Manual | Built-in | | Error contract konsisten | Manual | Built-in | | DX untuk pemula | Cukup teknis | Lebih ramah | | Struktur project scalable | Manual | Lebih siap |

[!TIP] 💡 APEX cocok untuk aplikasi frontend, admin dashboard, SPA, SSR ringan, tooling internal, dan service layer yang butuh pola request konsisten.

Cocok untuk siapa

| Tipe pengguna | Alasan | | ------------------------------- | -------------------------------------------------------------------------- | | Pemula | Lebih sedikit boilerplate dibanding fetch mentah untuk kebutuhan harian. | | Frontend developer | Mudah membuat service layer yang konsisten antar endpoint. | | Team lead | Lebih mudah menjaga standar error handling dan request configuration. | | Maintainer library internal | Struktur class dan helper membuat codebase lebih gampang diperluas. |


Fitur Utama

| Fitur | Status | Keterangan | | ---------------- | ------ | ---------------------------------------------------------- | | createApex() | Siap | Factory utama untuk membuat client | | HTTP shortcuts | Siap | get, post, put, patch, delete, head, options | | baseURL | Siap | Menggabungkan base URL dengan path request | | params | Siap | Query string serialization | | Auto JSON body | Siap | Plain object dan array di-serialize otomatis | | Auto JSON parse | Siap | responseType: "auto" mendeteksi JSON | | timeout | Siap | Berbasis AbortController | | retry | Siap | Network error, timeout, dan status tertentu | | Hooks | Siap | onRequest, onResponse, onError | | Error model | Siap | ApexError dengan code, status, request, response | | extend() | Siap | Clone instance dengan config baru | | TypeScript-first | Siap | Type contract konsisten |

🧩 Singkatnya, APEX memberi Anda tiga keuntungan utama sekaligus: kenyamanan konfigurasi, ketahanan request flow, dan kontrak data yang lebih jelas.


Instalasi

📦 Bagian ini menjelaskan cara mulai menggunakan APEX dengan cepat dan benar.

1. Install package

npm install apex-fetch

2. Pastikan runtime mendukung fetch

APEX dirancang untuk:

  • Browser modern
  • Node.js 18+

3. Import dari package

import { createApex } from "apex-fetch";

[!INFO] ℹ️ Jika Anda berada di Node.js lama yang belum menyediakan fetch native, Anda perlu menyediakan implementasi fetch sendiri melalui konfigurasi fetch.

4. Tentukan gaya pemakaian Anda

APEX bisa dipakai dalam dua pola utama:

  • langsung di komponen atau action untuk kebutuhan cepat
  • melalui service layer untuk project yang lebih rapi dan scalable

Quick Start

import { createApex } from "apex-fetch";

const api = createApex({
  baseURL: "https://api.example.com",
  timeout: 10000,
  retry: {
    limit: 2,
  },
});

const res = await api.get<{ id: number; name: string }>("/users/1");

console.log(res.data);
console.log(res.status);

Apa yang terjadi pada contoh di atas

  • 🌐 baseURL membuat endpoint relatif menjadi lebih pendek dan konsisten
  • ⏱️ timeout melindungi request agar tidak menggantung terlalu lama
  • 🔁 retry.limit memberi kesempatan request pulih dari gangguan sementara
  • 📦 res.data memberi payload hasil parsing tanpa membuat Anda kehilangan akses ke metadata response

Jika Anda baru mulai, contoh ini sudah cukup untuk membangun request layer yang sehat sejak awal.


Pola Penggunaan Step by Step

🪜 Di bawah ini adalah urutan pemakaian yang paling mudah dipahami dari nol sampai siap dipakai di project nyata.

Step 1 — Buat client utama

import { createApex } from "apex-fetch";

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

Step 2 — Tambahkan konfigurasi dasar

const api = createApex({
  baseURL: "https://api.example.com",
  timeout: 8000,
  headers: {
    Accept: "application/json",
  },
});

Step 3 — Kirim request GET

const res = await api.get<{ items: string[] }>("/items");

console.log(res.data.items);

Step 4 — Kirim request dengan query params

const res = await api.get("/search", {
  params: {
    page: 1,
    keyword: "apex",
    tag: ["fetch", "typescript"],
  },
});

Step 5 — Kirim request POST JSON

const res = await api.post("/users", {
  name: "Fauzan",
  role: "admin",
});

Step 6 — Tangani error dengan aman

import { isApexError } from "apex-fetch";

try {
  await api.get("/private");
} catch (err) {
  if (isApexError(err)) {
    console.error(err.code);
    console.error(err.status);
  }
}

Ringkasan hasil akhir

Setelah enam langkah di atas, Anda sudah punya fondasi request layer yang:

  • lebih konsisten daripada fetch mentah
  • lebih aman terhadap timeout dan error umum
  • lebih gampang dipakai ulang di berbagai file atau service

API Utama

🧱 API publik APEX sengaja dibuat ringkas agar mudah diingat, tetapi tetap cukup kuat untuk kebutuhan proyek yang serius.

Factory

| API | Deskripsi | | --------------------- | -------------------------- | | createApex(config?) | Membuat instance APEX baru |

Client Methods

| Method | Deskripsi | | ---------------------------- | --------------------------- | | request(config) | Jalur paling fleksibel | | get(url, config?) | Request GET | | post(url, body?, config?) | Request POST | | put(url, body?, config?) | Request PUT | | patch(url, body?, config?) | Request PATCH | | delete(url, config?) | Request DELETE | | head(url, config?) | Request HEAD | | options(url, config?) | Request OPTIONS | | extend(config?) | Membuat turunan client baru |

Error Utilities

| Utility | Deskripsi | | -------------------- | ---------------------------------------- | | ApexError | Error class utama APEX | | isApexError(value) | Type guard untuk identifikasi error APEX |

Catatan penting tentang extend()

extend() sangat berguna saat Anda ingin membuat client turunan tanpa mengulang seluruh konfigurasi. Pola ini sangat cocok untuk:

  • client authenticated
  • client admin
  • client per-module
  • client per-tenant

Lifecycle Request

🔄 Secara garis besar, alur internal APEX berjalan seperti ini:

| Tahap | Deskripsi | | ----------------------- | ---------------------------------------------------------------------------------- | | 1. merge config | Config instance dan config request digabung lebih dulu. | | 2. resolve request | Default config dirapikan menjadi bentuk final yang siap dipakai. | | 3. build URL | baseURL dan params disusun menjadi URL final. | | 4. build body | Body diproses dan header seperti content-type disesuaikan. | | 5. run request hooks | Semua onRequest dijalankan sebelum request dikirim. | | 6. send fetch | Request dikirim memakai fetch yang aktif. | | 7. evaluate retry | APEX memutuskan apakah perlu retry berdasarkan error atau status response. | | 8. parse response | Response diubah menjadi data sesuai responseType. | | 9. run response hooks | Semua onResponse dijalankan setelah parsing selesai. | | 10. assert HTTP | Jika throwOnHTTPError aktif, status 4xx/5xx akan dilempar sebagai ApexError. | | 11. run error hooks | Jika flow gagal, onError dijalankan sebelum error dilempar keluar. |

Lifecycle ini penting karena membantu Anda memahami di mana sebuah error muncul, kapan hook dieksekusi, dan mengapa retry bisa terjadi.


Konfigurasi Request

⚙️ Semua method APEX pada akhirnya bermuara ke ApexRequestConfig. Memahami objek ini berarti memahami hampir seluruh kekuatan library.

| Opsi | Tipe | Default | Keterangan | | ------------------ | --------------------- | -------------- | -------------------------------- | | url | string | "" | Path atau URL absolut | | method | string | "GET" | HTTP method | | baseURL | string | undefined | Prefix URL | | headers | HeadersInit | {} | Header request | | params | Record<string, ...> | undefined | Query params | | body | unknown | undefined | Body request | | timeout | number | 0 | Timeout dalam ms | | retry | number \| object | 0 | Retry policy | | responseType | "auto" \| ... | "auto" | Mode parsing response | | parseJson | boolean | true | Mengaktifkan parse JSON otomatis | | throwOnHTTPError | boolean | true | Lempar error saat 4xx/5xx | | credentials | RequestCredentials | undefined | Credential mode | | signal | AbortSignal | undefined | External abort signal | | fetch | typeof fetch | native fetch | Override fetch implementation | | hooks | Partial<ApexHooks> | kosong | Hook lifecycle |

Cara membaca config ini

  • baseURL + url membentuk alamat akhir request
  • params diubah menjadi query string
  • body akan di-serialize otomatis jika berupa object atau array biasa
  • timeout bekerja lewat AbortController
  • retry bisa berupa angka singkat atau object detail
  • responseType menentukan bagaimana response diparse

Tipe Response

🧪 APEX mendukung beberapa mode parsing supaya Anda bisa menyesuaikan output dengan kebutuhan endpoint.

| responseType | Hasil | Kapan dipakai | | --------------- | ---------------------------------------------------------------------- | ------------------------------------------------ | | "auto" | Menebak JSON bila memungkinkan, selain itu mengikuti fallback internal | Cocok untuk sebagian besar API JSON modern | | "json" | Memaksa parse JSON | Saat endpoint dipastikan selalu JSON | | "text" | Mengembalikan string | Untuk health check, plain text, atau HTML ringan | | "blob" | Mengembalikan Blob | Cocok untuk browser file preview atau download | | "arrayBuffer" | Mengembalikan ArrayBuffer | Untuk binary processing | | "formData" | Mengembalikan FormData | Untuk endpoint yang memang merespons form-data | | "raw" | Mengembalikan objek Response sebagai data | Saat Anda butuh kontrol manual penuh |

[!TIP] 🎯 Jika Anda tidak punya kebutuhan khusus, gunakan responseType: "auto" karena itu adalah mode yang paling nyaman untuk mayoritas kasus API JSON.

Response Contract

APEX mengembalikan wrapper response yang konsisten.

type ApexResponse<T> = {
  data: T;
  status: number;
  statusText: string;
  headers: Headers;
  url: string;
  ok: boolean;
  raw: Response;
};

Keuntungan pendekatan ini

  • 🔍 lebih informatif
  • 🛠️ lebih mudah di-debug
  • 📈 siap untuk scaling
  • 📬 tidak memaksa developer kehilangan akses ke status dan headers

Kenapa tidak langsung mengembalikan body saja

Karena di dunia nyata, developer sering tetap membutuhkan:

  • status code untuk branching logic
  • headers untuk pagination, token refresh, atau metadata
  • raw response untuk kasus lanjutan

Dengan kontrak response seperti ini, APEX menjaga payload tetap nyaman diakses tanpa membuang konteks penting.


Error Contract

🧯 APEX menggunakan class ApexError dengan struktur yang seragam supaya penanganan error tidak liar antar endpoint.

| Code | Arti | | ------------------ | ------------------------------ | | ERR_APEX_NETWORK | Gagal network request | | ERR_APEX_TIMEOUT | Request melebihi batas timeout | | ERR_APEX_ABORTED | Request dibatalkan | | ERR_APEX_HTTP | HTTP response tidak ok | | ERR_APEX_PARSE | Gagal parse response | | ERR_APEX_CONFIG | Konfigurasi tidak valid | | ERR_APEX_UNKNOWN | Error tidak dikenal |

Cara membaca ApexError

Biasanya Anda akan memeriksa beberapa properti ini:

  • error.code untuk klasifikasi masalah
  • error.status untuk HTTP failure
  • error.request untuk melihat config final yang dipakai
  • error.response untuk memeriksa metadata response jika tersedia

Contoh penanganan error

import { createApex, isApexError } from "apex-fetch";

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

try {
  await api.get("/reports");
} catch (err) {
  if (isApexError(err)) {
    console.error(err.code);
    console.error(err.status);
    console.error(err.request);
  }
}

Retry Strategy

🔁 APEX mendukung retry sederhana maupun detail. Tujuannya bukan membuat semua request diulang tanpa aturan, tetapi memberikan kebijakan retry yang eksplisit dan terkontrol.

Bentuk singkat

const api = createApex({
  retry: 2,
});

Bentuk detail

const api = createApex({
  retry: {
    limit: 3,
    delay: 300,
    backoff: "exponential",
    retryOnTimeout: true,
    retryOnNetworkError: true,
    retryOnStatuses: [408, 429, 500, 502, 503, 504],
  },
});

Backoff yang didukung

| Mode | Perilaku | | ------------- | ---------------------------- | | static | Delay tetap | | linear | Delay bertambah linear | | exponential | Delay bertambah eksponensial |

[!TIP] 🛡️ Untuk endpoint idempoten seperti GET, retry sangat cocok. Untuk request tertentu yang membawa stream sekali pakai, replay mungkin tidak aman.

Kapan retry sebaiknya dipakai

  • ya untuk GET, status sementara seperti 503, dan gangguan jaringan ringan
  • hati-hati untuk request dengan side effect
  • hindari jika body tidak aman untuk dikirim ulang

Hooks

🪝 APEX menyediakan tiga jenis hook utama untuk observability, enrichment, dan error handling.

| Hook | Waktu berjalan | | ------------ | ------------------------------------- | | onRequest | Sebelum request dikirim | | onResponse | Setelah response diterima dan diparse | | onError | Saat flow request gagal |

Kegunaan hook di dunia nyata

  • onRequest untuk menambah header, tracing, atau audit metadata
  • onResponse untuk logging status, analytics, atau transform lanjutan di level observasi
  • onError untuk pelaporan error, toast, Sentry bridge, atau metric internal

Contoh hook global

const api = createApex({
  hooks: {
    onRequest: [
      ({ request }) => {
        request.headers.set("x-client", "apex");
      },
    ],
    onResponse: [
      ({ response }) => {
        console.log("status:", response.status);
      },
    ],
    onError: [
      ({ error }) => {
        console.error("apex error:", error.code);
      },
    ],
  },
});

Contoh Real Code

1. Service layer untuk aplikasi dashboard

import { createApex } from "apex-fetch";

const api = createApex({
  baseURL: "https://api.example.com",
  timeout: 10000,
  headers: {
    Accept: "application/json",
  },
  retry: {
    limit: 2,
    delay: 250,
    backoff: "exponential",
  },
});

export async function getUsers() {
  const res = await api.get<{ id: number; name: string }[]>("/users");
  return res.data;
}

export async function createUser(data: { name: string; role: string }) {
  const res = await api.post<{ id: number; name: string }>("/users", data);
  return res.data;
}

2. Client turunan untuk endpoint authenticated

import { createApex } from "apex-fetch";

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

export function makeAuthApi(token: string) {
  return api.extend({
    headers: {
      Authorization: `Bearer ${token}`,
    },
  });
}

3. Request dengan response text

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

const res = await api.get<string>("/health", {
  responseType: "text",
  throwOnHTTPError: false,
});

console.log(res.data);

4. Penggunaan custom fetch

import { createApex } from "apex-fetch";

const api = createApex({
  fetch: globalThis.fetch,
});

Build dan Validasi

🧪 Sebelum APEX dipakai lebih jauh, project sudah divalidasi lewat type check, test suite, dan build output.

Perintah yang tersedia:

npm run check
npm run test
npm run build

Status validasi saat ini

| Validation | Status | | ------------ | ---------------- | | Type check | Lulus | | Test suite | Lulus | | Timeout test | Sudah diperbaiki | | Retry test | Lulus | | Hook test | Lulus |


FAQ

Apakah APEX menggantikan fetch native?

Tidak. 🙂 APEX justru dibangun di atas fetch native. Tujuannya adalah memberi lapisan ergonomis dan stabil, bukan menciptakan runtime baru.

Kapan saya sebaiknya memakai createApex() satu kali lalu extend()?

Saat project punya banyak domain API atau banyak variasi auth. Dengan pola ini, Anda bisa punya satu base client lalu membuat turunan yang lebih spesifik untuk tiap kebutuhan.

Apakah APEX cocok untuk project kecil?

Cocok. 🌱 Untuk project kecil, manfaat terbesarnya adalah pengurangan boilerplate. Untuk project besar, manfaat terbesarnya adalah konsistensi dan skalabilitas.

Apakah saya masih bisa memakai fetch custom?

Bisa. 🔌 Anda dapat mengisi properti fetch di config jika ingin memakai implementasi fetch lain yang kompatibel.

Kapan saya harus memakai responseType: "raw"?

Gunakan saat Anda ingin memegang Response secara manual, misalnya untuk kebutuhan parsing khusus, stream handling, atau kontrol header yang lebih eksplisit.

Kenapa response APEX tidak langsung hanya data?

Karena dalam aplikasi nyata, status, headers, ok, dan raw response sering tetap dibutuhkan. APEX menjaga keseimbangan antara kemudahan akses payload dan kelengkapan metadata. 📬


Legal Notice

[!WARNING] ⚖️ APEX Fetch tidak dirilis dengan lisensi open-source. Keberadaan package di registry publik tidak berarti source code boleh digunakan, dimodifikasi, atau didistribusikan ulang secara bebas.

Ringkasan legal

  • 🚫 Tidak boleh menyalin source tanpa izin
  • 🚫 Tidak boleh memodifikasi atau membuat turunan tanpa izin
  • 🚫 Tidak boleh mendistribusikan ulang tanpa izin
  • 🚫 Tidak boleh menjual, membundel ulang, atau white-label tanpa izin

Silakan baca file LICENSE untuk ketentuan lengkap.


Penutup

🏁 APEX Fetch dirancang untuk developer yang menginginkan lapisan fetch yang:

  • cepat
  • stabil
  • presisi
  • mudah di-setup
  • nyaman untuk dipakai harian
  • cukup fleksibel untuk project yang berkembang

Jika tujuan Anda adalah membuat request layer yang bersih, konsisten, mudah dipahami, dan siap tumbuh bersama project, maka APEX adalah fondasi yang tepat. ✨