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

fetchero

v0.1.5

Published

_A type-safe, proxy-based HTTP & GraphQL client for modern applications._

Readme

Fetchero

A type-safe, proxy-based HTTP & GraphQL client for modern applications.

fetchero is a lightweight, flexible, and highly intuitive library for making REST and GraphQL requests.
It uses Proxies for a chainable API, interceptors for pre/post-processing, and enhanced error handling for safer, predictable responses.

Whether you're consuming REST APIs or working with GraphQL backends, Fetchero simplifies the process with a declarative, fluent syntax that feels natural and reduces boilerplate.


Table of Contents

  1. Features
  2. Installation
  3. Basic Usage
  4. REST Client
  5. GraphQL Client
  6. Interceptors
  7. Error Handling
  8. Response Shape
  9. Examples
  10. TypeScript Support
  11. API Overview
  12. Why Fetchero?

Features

  • Proxy-based REST client — Build endpoints dynamically using dot-chaining and path arguments. No manual string concatenation.

  • GraphQL client with query builder — Write GraphQL queries fluently, with support for variables and field selection.

  • Base URL & dynamic headers — Override base URLs and headers globally or per-request.

  • Interceptors — Hook into requests and responses for logging, authentication, and transformation.

  • Error handling — Standardized error objects with meaningful messages and GraphQL error normalization.

  • Fully TypeScript ready — Get autocompletion and type safety for your API calls.


Installation

npm install fetchero

or

yarn add fetchero

Basic Usage

Create an instance

import { createFetchero } from 'fetchero';

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

Or individually

If you only need one client type (REST or GraphQL):

import { rest, gql } from 'fetchero';
const restClient = rest({ baseUrl: '...' });
const gqlClient = gql({ baseUrl: '...' });

REST Client

Making requests

// GET /users
const res = await api.rest.users.get();

// GET /users/123
const res = await api.rest.users(123).get();

// GET /users/123?active=true
const res = await api.rest.users(123).get({ query: { active: true } });

// POST /users with body
const res = await api.rest.users.post({ body: { name: 'John' } });

Dynamic path segments

// GET /users/123/posts/456
const res = await api.rest
  .users(123)
  .posts(456)
  .get();

Or you may like short syntax

// GET /users
const res = await api.rest('users').get();

// GET /users/123
const res = await api.rest('users', 123).get();

// POST /users/123/posts/456
const res = await api
  .rest('users', 123, 'posts', 345)
  .post({ body: { name: 'John' } });

Override base URL or headers

// Different base URL
await api.rest.users.base('https://another-api.com').get();

// Add/override headers
await api.rest.users.headers({ Authorization: 'Bearer new-token' }).get();

GraphQL Client

Fetchero provides a fluent query builder for GraphQL.

Queries

// Basic query
const res = await api.gql.query.getUser({ id: 123 }).select('id name email');

This builds and executes:

query {
  getUser(id: 123) {
    id
    name
    email
  }
}

Mutations

const res = await api.gql.mutation
  .createUser({ name: 'John' })
  .select('id name');

Subscriptions

const res = await api.gql.subscription
  .onMessage({ roomId: 1 })
  .select('id content');

Passing Arguments & Variables

Fetchero automatically converts JS objects into typed GraphQL variables.

Plain Arguments (Auto-inferred types)

await api.gql.query.getUser({ id: 1 }).select('id name');

Builds:

query my_query($id_0: Int) {
  getUser(id: $id_0) {
    id
    name
  }
}

Custom Types

Wrap values in { value, type } to define the GraphQL type explicitly:

await api.gql.query
  .getUser({ id: 1, status: { value: 'ACTIVE', type: 'StatusEnum!' } })
  .select('id name status');

Builds:

query my_query($id_0: Int, $status_0: StatusEnum!) {
  getUser(id: $id_0, status: $status_0) {
    id
    name
    status
  }
}

Nested Input Objects

You can pass complex input types like this:

await api.gql.mutation.updateUser({
  id: 1,
  profile: {
    type: 'UserProfileInput',
    value: { age: 30, email: '[email protected]' },
  },
});

Builds:

mutation my_mutation($id_0: Int, $profile_0: UserProfileInput) {
  updateUser(id: $id_0, profile: $profile_0)
}

Rules for Arguments

  • Plain values → Auto-inferred type (Int, String, Float).

  • { value, type } → Explicit GraphQL type.

  • Nested objects → Use { type: 'MyInputType', value: { ... } }.

  • Invalid values (arrays, functions, etc.) → Throw an error.


Override base URL & headers

await api.gql.query
  .getUser({ id: 123 })
  .base('https://graphql.alt.com')
  .headers({ Authorization: 'Bearer new' })
  .select('id name');

Interceptors

Intercept and modify requests and responses globally.

import { createFetchero } from 'fetchero';

const api = createFetchero({
  baseUrl: 'https://api.example.com',
  interceptors: {
    request: async config => {
      console.log('Outgoing Request:', config);
      return config;
    },
    response: async response => {
      console.log('Incoming Response:', response.data);
      return response.data;
    },
  },
});

Error Handling

All errors are standardized:

const res = await api.rest.users(999).get();

if (res.errors) {
  console.log(res.errors[0].extensions.message); // "Not Found"
}

GraphQL errors are automatically normalized using errorCompose.


Response Shape

Every request returns:

interface FetcherResponse<T> {
  data: T | null;
  errors?: Array<{
    message?: string;
    extensions: { code?: string; message?: string };
  }>;
}

Examples

Chained REST call with query & headers

await api.rest
  .users(42)
  .headers({ 'X-Custom': 'yes' })
  .posts.get({ query: { page: 2 } });

GraphQL query with variables

await api.gql.query
  .searchUsers({ name: { type: 'String!', value: 'John' } })
  .select('id name email');

TypeScript Support

Type definitions are included out of the box for:

  • REST responses

  • GraphQL queries/mutations

  • Errors & interceptors


API Overview

REST

  • api.rest[resource] — Chainable resource paths

  • Methods: .get(), .post(), .put(), .patch(), .delete()

  • Modifiers: .base(url), .headers({ ... })

GraphQL

  • api.gql.query.field(args).select(fields)

  • Operations: query, mutation, subscription

  • Modifiers: .base(url), .headers({ ... })


Why Fetchero?

  • No need to manually build URLs or queries.

  • Fluent, chainable API.

  • Works equally well for REST & GraphQL.

  • Easy integration with TypeScript & interceptors.