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 🙏

© 2025 – Pkg Stats / Ryan Hefner

guardz-axios

v1.11.3

Published

Type-safe HTTP client built on top of Axios with runtime validation using guardz. Part of the guardz ecosystem for comprehensive TypeScript type safety.

Readme

Guardz Axios

GitHub Sponsors

A type-safe HTTP client built on top of Axios with runtime validation using guardz 1.11.3+.

What This Library Does

Guardz Axios transforms your HTTP requests into type-safe operations that automatically validate response data at runtime. Instead of manually checking response types and handling errors, you get:

  • Automatic runtime validation of all response data
  • Type-safe results with discriminated unions
  • Comprehensive error handling with detailed feedback
  • Multiple API patterns for different use cases
  • Retry logic with configurable backoff strategies
  • Tolerance mode for graceful degradation

Installation

npm install guardz-axios guardz axios

Guardz Ecosystem

This library is part of the Guardz ecosystem - a comprehensive TypeScript type guard solution designed to bring runtime type safety to your applications:

🌟 Core Components

guardz - Core Type Guard Library

The foundation of the ecosystem, providing 50+ built-in type guards and utilities:

npm install guardz

Features:

  • 50+ built-in type guards for all JavaScript types
  • Composite type guards for complex validation
  • Custom type guard creation with isType() and isOneOf()
  • Array and object validation with isArrayOf() and isRecord()
  • Optional and nullable types with isOptional() and isNullable()
  • Union types with isUnion() and isOneOf()
  • Intersection types with isIntersection()

Example:

import { isType, isString, isNumber, isOptional, isArrayOf } from "guardz";

interface User {
  id: number;
  name: string;
  email?: string;
  tags: string[];
}

const isUser = isType<User>({
  id: isNumber,
  name: isString,
  email: isOptional(isString),
  tags: isArrayOf(isString),
});

// Runtime validation
if (isUser(data)) {
  // data is guaranteed to be User type
  console.log(data.name); // Type-safe access
}

guardz-generator - Automatic Type Guard Generation

Automatically generate type guards from your TypeScript interfaces and types:

npm install guardz-generator

Features:

  • Automatic generation from TypeScript interfaces
  • CLI tool for batch processing
  • Watch mode for development
  • Custom templates for specialized guards
  • Integration with build tools and IDEs

Usage:

# Generate guards from all TypeScript files
npx guardz-generator generate "src/**/*.ts"

# Watch mode for development
npx guardz-generator watch "src/**/*.ts"

# Generate guards for specific files
npx guardz-generator generate src/types/user.ts src/types/post.ts

Generated Output:

// Auto-generated from interface User
export const isUser = isType<User>({
  id: isNumber,
  name: isString,
  email: isOptional(isString),
  tags: isArrayOf(isString),
});

// Auto-generated from interface Post
export const isPost = isType<Post>({
  id: isNumber,
  title: isString,
  content: isString,
  author: isUser,
  publishedAt: isOptional(isString),
});

guardz-axios - Type-Safe HTTP Client

This package - a type-safe HTTP client with runtime validation:

npm install guardz-axios

Features:

  • Runtime validation of all HTTP responses
  • Type-safe results with discriminated unions
  • Multiple API patterns (curried, fluent, configuration-first)
  • Retry logic with exponential backoff
  • Tolerance mode for graceful degradation
  • Comprehensive error handling

Example:

import { safeGet } from "guardz-axios";
import { isUser } from "./guards"; // Generated by guardz-generator

const result = await safeGet({ guard: isUser })("/users/1");

if (result.status === Status.SUCCESS) {
  console.log(result.data.name); // Type-safe access
} else {
  console.error(`Error: ${result.message}`);
}

guardz-event - Type-Safe Event Handling

Type-safe event handling with runtime validation:

npm install guardz-event

Features:

  • Type-safe event emitters with runtime validation
  • Event type guards for payload validation
  • Event listeners with automatic type inference
  • Event middleware for transformation and filtering
  • Event history and replay capabilities
  • Integration with Node.js EventEmitter and browser events

Example:

import { createTypedEventEmitter } from "guardz-event";
import { isType, isString, isNumber } from "guardz";

interface UserCreatedEvent {
  userId: number;
  userName: string;
}

const isUserCreatedEvent = isType<UserCreatedEvent>({
  userId: isNumber,
  userName: isString,
});

const emitter = createTypedEventEmitter({
  "user:created": isUserCreatedEvent,
});

// Type-safe event emission
emitter.emit("user:created", { userId: 1, userName: "John" });

// Type-safe event listening
emitter.on("user:created", (event) => {
  console.log(`User created: ${event.userName} (ID: ${event.userId})`);
  // event is fully typed as UserCreatedEvent
});

🔄 Ecosystem Integration

The guardz ecosystem components work seamlessly together:

// 1. Define your types
interface User {
  id: number;
  name: string;
  email: string;
}

// 2. Generate type guards automatically
// npx guardz-generator generate "src/**/*.ts"
// This creates: src/guards/user.guards.ts

// 3. Use in HTTP requests
import { safeGet } from "guardz-axios";
import { isUser } from "./guards/user.guards";

const result = await safeGet({ guard: isUser })("/users/1");

// 4. Use in event handling
import { createTypedEventEmitter } from "guardz-event";

const emitter = createTypedEventEmitter({
  "user:updated": isUser,
});

emitter.on("user:updated", (user) => {
  // user is fully typed as User
  console.log(`User updated: ${user.name}`);
});

🚀 Getting Started with the Ecosystem

  1. Install the core packages:

    npm install guardz guardz-generator guardz-axios guardz-event
  2. Set up automatic type guard generation:

    # Add to package.json scripts
    "scripts": {
      "generate:guards": "guardz-generator generate \"src/**/*.ts\"",
      "watch:guards": "guardz-generator watch \"src/**/*.ts\""
    }
  3. Generate guards from your types:

    npm run generate:guards
  4. Use in your application:

    import { safeGet } from "guardz-axios";
    import { createTypedEventEmitter } from "guardz-event";
    import { isUser, isPost } from "./guards"; // Auto-generated
    
    // Type-safe HTTP requests
    const userResult = await safeGet({ guard: isUser })("/users/1");
    
    // Type-safe event handling
    const emitter = createTypedEventEmitter({
      "user:created": isUser,
      "post:published": isPost,
    });

📚 Documentation Links

🎯 Use Cases

The guardz ecosystem is perfect for:

  • API Development - Validate all incoming/outgoing data
  • Event-Driven Applications - Type-safe event handling
  • Microservices - Ensure data consistency across services
  • Frontend Applications - Validate API responses and user input
  • Backend Services - Validate database queries and external API calls
  • Testing - Generate type-safe test data and mocks

🔧 Development Workflow

  1. Define your types in TypeScript interfaces
  2. Generate type guards automatically with guardz-generator
  3. Use guards in your HTTP requests with guardz-axios
  4. Handle events type-safely with guardz-event
  5. Enjoy full runtime type safety across your application

Quick Start

import { safeGet } from "guardz-axios";
import { isType, isString, isNumber } from "guardz";
import { Status } from "guardz-axios";

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

const isUser = isType<User>({
  id: isNumber,
  name: isString,
  email: isString,
});

const result = await safeGet({ guard: isUser })("/users/1");

if (result.status === Status.SUCCESS) {
  console.log("User:", result.data); // Fully typed as User
} else {
  console.log("Error:", result.code, result.message);
}

How It Works

Result Type

The library uses a discriminated union for type-safe results:

type SafeRequestResult<T> =
  | { status: Status.SUCCESS; data: T }
  | { status: Status.ERROR; code: number; message: string };

Success Response

When the request succeeds and validation passes:

{
  status: Status.SUCCESS,
  data: T // Your validated data
}

Error Response

When the request fails or validation fails:

{
  status: Status.ERROR,
  code: number,    // HTTP status code or 500 for validation errors
  message: string  // Human-readable error message
}

Error Types and Messages

1. Validation Errors (Code: 500)

When response data doesn't match the expected type:

{
  status: Status.ERROR,
  code: 500,
  message: "Response data validation failed: Expected userData.id (\"1\") to be \"number\""
}

2. Network Errors (Code: 500)

When network requests fail:

{
  status: Status.ERROR,
  code: 500,
  message: "Network Error"
}

3. Timeout Errors (Code: 500)

When requests timeout:

{
  status: Status.ERROR,
  code: 500,
  message: "timeout of 5000ms exceeded"
}

4. HTTP Status Errors

When the server returns error status codes:

{
  status: Status.ERROR,
  code: 404,
  message: "Not Found"
}

Error Handling Examples

Basic Error Handling

const result = await safeGet({ guard: isUser })("/users/1");

if (result.status === Status.SUCCESS) {
  console.log("Success:", result.data);
} else {
  console.error(`Request failed: ${result.message}`);
  console.error(`Status: ${result.code}`);
}

Tolerance Mode Error Handling

const result = await safeGet({
  guard: isUser,
  tolerance: true,
  onError: (error, context) => {
    console.warn(`Validation warning: ${error}`);
    console.warn(`Context: ${context.url} (${context.method})`);
  },
})("/users/1");

if (result.status === Status.SUCCESS) {
  console.log("Data is valid:", result.data);
} else {
  console.log("Request failed:", result.message);
}

Retry with Error Handling

const result = await safeRequest({
  url: "/users/1",
  method: "GET",
  guard: isUser,
  retry: {
    attempts: 3,
    delay: 1000,
    backoff: "exponential",
  },
});

if (result.status === Status.SUCCESS) {
  console.log("Request succeeded:", result.data);
} else {
  console.error(`Request failed: ${result.message}`);
}

Error Handling

The library provides detailed error messages and multiple error handling strategies:

Best Practices for Error Handling

  1. Always check the status first:

    if (result.status === Status.SUCCESS) {
      // Handle success
    } else {
      // Handle error
    }
  2. Handle different error types appropriately:

    if (result.status === Status.ERROR) {
      switch (result.code) {
        case 404:
          // Handle not found
          break;
        case 500:
          // Handle server errors
          break;
      }
    }
  3. Use tolerance mode for graceful degradation:

    const result = await safeGet({
      guard: isUser,
      tolerance: true,
    })("/users/1");
    
    if (result.status === Status.SUCCESS) {
      // Use data confidently
    } else {
      // Handle error
    }
  4. Use detailed error messages:

    const result = await safeGet({
      guard: isUser,
      onValidationError: (errors) => {
        errors.forEach((error) => {
          console.error(`Validation failed: ${error}`);
        });
      },
    })("/users/1");

API Patterns

Pattern 1: Curried Functions

Simple, functional approach:

import { safeGet, safePost } from "guardz-axios";

const getUser = safeGet({ guard: isUser });
const createUser = safePost({ guard: isUser });

const result = await getUser("/users/1");
if (result.status === Status.SUCCESS) {
  console.log("User:", result.data);
}

Pattern 2: Configuration-first

Full control over request configuration:

import { safeRequest } from "guardz-axios";

const result = await safeRequest({
  url: "/users/1",
  method: "GET",
  guard: isUser,
  timeout: 5000,
  retry: {
    attempts: 3,
    delay: 1000,
    backoff: "exponential",
  },
});

if (result.status === Status.SUCCESS) {
  console.log("User:", result.data);
}

Pattern 3: Fluent API Builder

Chainable, readable API:

import { safe } from "guardz-axios";

const result = await safe()
  .get("/users/1")
  .guard(isUser)
  .timeout(5000)
  .retry({ attempts: 3, delay: 1000 })
  .execute();

if (result.status === Status.SUCCESS) {
  console.log("User:", result.data);
}

Pattern 4: Context/Provider

Shared configuration across requests:

import { createSafeApiContext } from "guardz-axios";

const api = createSafeApiContext({
  baseURL: "https://api.example.com",
  timeout: 5000,
  defaultTolerance: true,
});

const result = await api.get("/users/1", { guard: isUser });
if (result.status === Status.SUCCESS) {
  console.log("User:", result.data);
}

Advanced Features

Tolerance Mode

Handle invalid responses gracefully:

const result = await safeGet({
  guard: isUser,
  tolerance: true,
  onError: (error, context) => {
    console.warn(`Validation warning: ${error}`);
  },
})("/users/1");

if (result.status === Status.SUCCESS) {
  console.log("User:", result.data);
} else {
  console.log("Request failed:", result.message);
}

Retry Logic

Automatic retry with exponential backoff:

const result = await safeGet({
  guard: isUser,
  retry: {
    attempts: 3,
    delay: 1000,
    backoff: "exponential",
    retryOn: (error) => {
      // Custom retry logic
      return error.message.includes("network");
    },
  },
})("/users/1");

if (result.status === Status.SUCCESS) {
  console.log("User:", result.data);
}

Custom Axios Instance

Use your own Axios configuration:

import axios from "axios";

const customAxios = axios.create({
  baseURL: "https://api.example.com",
  headers: { Authorization: "Bearer token" },
});

const result = await safeGet({
  guard: isUser,
  axiosInstance: customAxios,
})("/users/1");

if (result.status === Status.SUCCESS) {
  console.log("User:", result.data);
}

Type Safety

Automatic Type Inference

const result = await safeGet({ guard: isUser })("/users/1");

if (result.status === Status.SUCCESS) {
  // TypeScript knows this is User
  console.log(result.data.name); // ✅ Type-safe
  console.log(result.data.email); // ✅ Type-safe
}

Type Guards

import { isType, isString, isNumber } from "guardz";

const isUser = isType<User>({
  id: isNumber,
  name: isString,
  email: isString,
});

const result = await safeGet({ guard: isUser })("/users/1");

💡 Tip: Use guardz-generator to automatically generate type guards from your TypeScript interfaces instead of writing them manually!

Examples

See the examples directory for complete working examples:

Sponsors

Support this project by becoming a sponsor:

License

MIT