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

@axlotl-lab/ghola-fetch

v1.8.1

Published

A modern, flexible and powerful HTTP client for browser and Node.js environments, built on top of the Fetch API. Named after the "Ghola" concept from Frank Herbert's Dune series, this library recreates and enhances the native fetch functionality with addi

Readme

GholaFetch

A modern, flexible and powerful HTTP client for browser and Node.js environments, built on top of the Fetch API. Named after the "Ghola" concept from Frank Herbert's Dune series, this library recreates and enhances the native fetch functionality with additional features.

npm version License: MIT

Features

  • Built on the native Fetch API
  • Supports both instance and static usage patterns (like Axios)
  • Powerful middleware system for request/response transformation
  • Automatic content type detection and parsing
  • Integrated caching with Cache-Control support
  • Comprehensive error handling
  • TypeScript support
  • Works in both browser and Node.js environments

Installation

# Using npm
npm install @axlotl-lab/ghola-fetch

Basic Usage

Static Usage (Similar to Axios)

import { GholaFetch } from '@axlotl-lab/ghola-fetch';

// Optional global configuration
GholaFetch.create({
  baseUrl: 'https://api.example.com',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your-token'
  }
});

// Simple GET request
const getUserData = async () => {
  try {
    const response = await GholaFetch.get('/users/123');
    console.log(response.data);
  } catch (error) {
    console.error('Error fetching user:', error);
  }
};

// POST request with data
const createUser = async () => {
  try {
    const response = await GholaFetch.post('/users', {
      body: {
        name: 'John Doe',
        email: '[email protected]'
      }
    });
    console.log('User created:', response.data);
  } catch (error) {
    console.error('Error creating user:', error);
  }
};

Instance Usage (For Multiple Configurations)

import { GholaFetch } from '@axlotl-lab/ghola-fetch';

// Create instance for specific API
const usersApi = new GholaFetch({
  baseUrl: 'https://api.users.example.com',
  headers: {
    'Authorization': 'Bearer users-api-token'
  }
});

// Create another instance for a different API
const productsApi = new GholaFetch({
  baseUrl: 'https://api.products.example.com',
  headers: {
    'Authorization': 'Bearer products-api-token'
  }
});

// Use different instances
const fetchData = async () => {
  const users = await usersApi.get('/users');
  const products = await productsApi.get('/products');
  
  return { users: users.data, products: products.data };
};

Advanced Usage

Working with Middleware

Middlewares allow you to intercept and transform requests before they are sent and responses before they are returned:

import { GholaFetch, GholaMiddleware } from '@axlotl-lab/ghola-fetch';

// Authentication middleware
const authMiddleware: GholaMiddleware = {
  pre: async (options) => {
    // Add authentication token to all requests
    const token = localStorage.getItem('auth_token');
    if (token) {
      options.options = options.options || {};
      options.options.headers = options.options.headers || {};
      options.options.headers['Authorization'] = `Bearer ${token}`;
    }
    return options;
  }
};

// Logging middleware
const loggingMiddleware: GholaMiddleware = {
  pre: async (options) => {
    console.log(`Request to: ${options.baseUrl || ''}${options.endpoint}`);
    return options;
  },
  post: async (response) => {
    console.log(`Response status: ${response.status}`);
    return response;
  }
};

// Error handling middleware
const errorMiddleware: GholaMiddleware = {
  post: async (response) => {
    if (response.status === 401) {
      // Handle unauthorized access
      window.location.href = '/login';
    }
    return response;
  }
};

// Add middlewares to the global instance
GholaFetch.use(authMiddleware);
GholaFetch.use(loggingMiddleware);
GholaFetch.use(errorMiddleware);

// Or add middlewares to a specific instance
const api = new GholaFetch({ baseUrl: 'https://api.example.com' });
api.use(authMiddleware)
   .use(loggingMiddleware)
   .use(errorMiddleware);

Handling Different Content Types

GholaFetch automatically detects and parses different response types based on the Content-Type header:

// JSON data (default)
const getJsonData = async () => {
  const response = await GholaFetch.get('/api/data');
  console.log(response.data); // Automatically parsed JSON
};

// Text content
const getTextData = async () => {
  const response = await GholaFetch.get('/api/text');
  console.log(response.data); // Text string
};

// Binary data
const getBinaryData = async () => {
  const response = await GholaFetch.get('/api/binary');
  // For endpoints that return binary data with Content-Type: application/octet-stream
  const binaryData = response.data; // Blob object in browser, Buffer in Node.js
};

// Form data
const submitFormData = async () => {
  const formData = new FormData();
  formData.append('name', 'John Doe');
  formData.append('avatar', fileInput.files[0]);
  
  const response = await GholaFetch.post('/api/upload', {
    body: formData
    // No need to set Content-Type, it's handled automatically
  });
};

Caching

GholaFetch supports response caching based on Cache-Control headers:

import { GholaFetch, MemoryCache } from '@axlotl-lab/ghola-fetch';

// Create a memory cache
const cache = new MemoryCache();

// Configure GholaFetch with cache
GholaFetch.create({
  baseUrl: 'https://api.example.com',
  cache
});

// Requests to the same endpoint will be cached according to Cache-Control headers
const getData = async () => {
  // First call fetches from server
  const response1 = await GholaFetch.get('/api/data');
  
  // Second call might return from cache if the server sent appropriate Cache-Control headers
  const response2 = await GholaFetch.get('/api/data');
};

Error Handling

GholaFetch provides comprehensive error handling:

import { GholaFetch, GholaFetchError } from '@axlotl-lab/ghola-fetch';

const handleData = async () => {
  try {
    const response = await GholaFetch.get('/api/data');
    return response.data;
  } catch (error) {
    if (error instanceof GholaFetchError) {
      // Access to the response object
      console.error(`HTTP Error ${error.status}: ${error.message}`);
      
      // Original response data might contain error details from the server
      if (error.response && error.response.data) {
        console.error('Server message:', error.response.data);
      }
      
      // Handle specific error codes
      if (error.status === 404) {
        return { notFound: true };
      } else if (error.status === 401) {
        // Redirect to login
        window.location.href = '/login';
      }
    } else {
      // Network errors or other unexpected errors
      console.error('Unexpected error:', error);
    }
    
    // Return fallback data
    return { error: true, message: 'Failed to fetch data' };
  }
};

TypeScript Support

GholaFetch fully supports TypeScript, allowing you to specify the response data type:

interface User {
  id: number;
  name: string;
  email: string;
}

// Specify the response data type
const getUser = async (id: number): Promise<User> => {
  const response = await GholaFetch.get<User>(`/users/${id}`);
  return response.data;
};

// With array responses
const getUsers = async (): Promise<User[]> => {
  const response = await GholaFetch.get<User[]>('/users');
  return response.data;
};

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.