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

@kudoengineer/http

v1.0.0

Published

Modern, lightweight and production-ready HTTP client library for Angular with base URL configuration, authentication, retry, timeout, cancellation, caching, request deduplication, request IDs, logging and reactive Signals support.

Readme

@kudoengineer/http

Modern, lightweight and production-ready HTTP client library for Angular.

@kudoengineer/http provides a clean and powerful API on top of Angular HttpClient, with built-in support for authentication, retry policies, timeout, cancellation, caching, request deduplication, request IDs, logging and Angular Signals.

Built for modern Angular applications and scalable enterprise projects.


✨ Features

  • ✅ Angular Standalone support
  • ✅ TypeScript support
  • ✅ GET, POST, PUT, PATCH, DELETE, HEAD and OPTIONS
  • ✅ Base URL configuration
  • ✅ Global headers
  • ✅ Request-specific headers
  • ✅ Query parameters
  • ✅ Authentication / Token Provider
  • ✅ JWT / Bearer token support
  • ✅ URL include/exclude authentication rules
  • ✅ Automatic error normalization
  • ✅ Retry with exponential backoff
  • ✅ Configurable retry status codes
  • ✅ Request timeout
  • ✅ Request cancellation with AbortSignal
  • ✅ Request ID generation
  • ✅ HTTP request/response logging
  • ✅ Cache-first strategy
  • ✅ Network-first strategy
  • ✅ Force-cache strategy
  • ✅ Cache invalidation
  • ✅ Request deduplication
  • ✅ Angular Signals based HTTP resource
  • ✅ Tree-shakable
  • ✅ Lightweight
  • ✅ Production ready
  • ✅ No dependency on @kudoengineer/loader

📦 Installation

Install the package using npm:

npm install @kudoengineer/http

🔧 Requirements

Supported Angular versions:

  • Angular 20
  • Angular 21
  • Angular 22
  • Angular 23

The package requires:

@angular/common
@angular/core

🚀 Basic Setup

1. Import providers

In your Angular application, add:

import { ApplicationConfig } from '@angular/core';

import { provideKudoHttp, provideKudoHttpInterceptors } from '@kudoengineer/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideKudoHttp({
      baseUrl: 'https://api.example.com',
    }),

    provideKudoHttpInterceptors(),
  ],
};

🌐 Base URL

Configure a global API base URL:

provideKudoHttp({
  baseUrl: 'https://api.example.com',
});

Now:

this.http.get('/users');

will request:

https://api.example.com/users

You can also provide an absolute URL:

this.http.get('https://another-api.com/users');

Absolute URLs are not modified by the configured base URL.


📡 HTTP Service

Inject KudoHttpService:

import { Component, inject } from '@angular/core';

import { KudoHttpService } from '@kudoengineer/http';

@Component({
  selector: 'app-users',
  standalone: true,
  template: `...`,
})
export class UsersComponent {
  private readonly http = inject(KudoHttpService);
}

GET Request

this.http.get<User[]>('/users').subscribe((users) => {
  console.log(users);
});

POST Request

this.http
  .post<User>('/users', {
    name: 'Satendra',
    email: '[email protected]',
  })
  .subscribe((user) => {
    console.log(user);
  });

PUT Request

this.http
  .put<User>('/users/1', {
    name: 'Satendra Rajput',
  })
  .subscribe((user) => {
    console.log(user);
  });

PATCH Request

this.http
  .patch<User>('/users/1', {
    name: 'Satendra',
  })
  .subscribe((user) => {
    console.log(user);
  });

DELETE Request

this.http.delete('/users/1').subscribe(() => {
  console.log('User deleted');
});

HEAD Request

this.http.head('/users').subscribe((headers) => {
  console.log(headers);
});

OPTIONS Request

this.http.options('/users').subscribe((response) => {
  console.log(response);
});

🧾 Headers

Global Headers

Configure headers globally:

provideKudoHttp({
  baseUrl: 'https://api.example.com',

  headers: {
    'Content-Type': 'application/json',
    'X-Client': 'KudoEngineer',
  },
});

Request Headers

You can override/add headers for an individual request:

this.http.get('/users', {
  headers: {
    'X-Request-Type': 'admin',
  },
});

🔎 Query Parameters

Pass query parameters using an object:

this.http.get('/users', {
  params: {
    page: 1,
    size: 20,
    active: true,
  },
});

Generated URL:

/users?page=1&size=20&active=true

🔐 Authentication

@kudoengineer/http supports custom token providers.

Create a token provider:

const tokenProvider = {
  getAccessToken: () => {
    return localStorage.getItem('access_token');
  },
};

Configure authentication:

provideKudoHttpAuth(tokenProvider);

Complete configuration:

import { provideKudoHttpAuth } from '@kudoengineer/http';

providers: [provideKudoHttpAuth(tokenProvider)];

The default header is:

Authorization: Bearer <token>

🪪 Custom Authentication Header

provideKudoHttpAuth(tokenProvider, {
  headerName: 'X-Auth-Token',
  scheme: '',
});

🚫 Exclude URLs from Authentication

provideKudoHttpAuth(tokenProvider, {
  excludedUrls: ['/auth/login', '/auth/register', '/public'],
});

🎯 Include URLs

You can restrict authentication to specific URLs:

provideKudoHttpAuth(tokenProvider, {
  includeUrls: ['/api/', '/secure/'],
});

🔄 Retry

Enable global retry:

provideKudoHttp({
  baseUrl: 'https://api.example.com',

  retry: {
    enabled: true,
    count: 3,
    delay: 500,
    maxDelay: 5000,
  },
});

Default retryable status codes:

408
429
500
502
503
504

Network errors can also be retried.


🎯 Request-specific Retry

this.http.get('/users', {
  retry: {
    enabled: true,
    count: 5,
    delay: 1000,
    maxDelay: 10000,
  },
});

Request-level configuration overrides the global retry configuration.


⏱️ Timeout

Global timeout:

provideKudoHttp({
  timeout: 30000,
});

Request-specific timeout:

this.http.get('/users', {
  timeout: 10000,
});

The value is in milliseconds.


🛑 Request Cancellation

Use the standard AbortController API:

const controller = new AbortController();

this.http
  .get('/users', {
    signal: controller.signal,
  })
  .subscribe({
    next: (data) => {
      console.log(data);
    },
    error: (error) => {
      console.error(error);
    },
  });

Cancel the request:

controller.abort();

❌ Error Handling

The package normalizes HTTP errors into:

KudoHttpError;

Example:

this.http.get('/users').subscribe({
  next: (users) => {
    console.log(users);
  },

  error: (error) => {
    console.log(error.status);
    console.log(error.message);
    console.log(error.code);
  },
});

Available error codes include:

HTTP_ERROR
NETWORK_ERROR
TIMEOUT
UNKNOWN_ERROR

You can also configure a global error handler:

provideKudoHttp({
  onError: (error) => {
    console.error('[KudoHttp]', error);
  },
});

🆔 Request ID

Request IDs are enabled by default.

Every request receives:

X-Request-ID

Example:

X-Request-ID: 9c3d7...

This is useful for:

  • distributed tracing
  • debugging
  • backend log correlation
  • microservices
  • fintech applications

📝 Logging

Logging is disabled by default.

Enable it:

provideKudoHttpInterceptors({
  logging: true,
});

Example console output:

[KudoHttp] HTTP_REQUEST
[KudoHttp] HTTP_RESPONSE

Logging can include:

  • request method
  • URL
  • request ID
  • status
  • status text
  • duration

Sensitive headers and body data are not logged by default.


💾 Cache

Caching is opt-in per request.

Cache First

this.http.get('/users', {
  cache: {
    policy: 'cache-first',
    ttl: 60000,
  },
});

The cache is checked first.

If cached data exists, it is returned without making a network request.


🌐 Network First

this.http.get('/users', {
  cache: {
    policy: 'network-first',
    ttl: 60000,
  },
});

The network is requested first.

If the network request fails and valid cached data exists, cached data is returned.

This is useful for:

  • dashboards
  • configuration APIs
  • offline-friendly applications
  • mobile applications

⚡ Force Cache

this.http.get('/users', {
  cache: {
    policy: 'force-cache',
    ttl: 60000,
  },
});

Cached data is used when available.


🚫 Disable Cache

this.http.get('/users', {
  cache: {
    policy: 'no-cache',
  },
});

🗑️ Cache Invalidation

Inject:

import { KudoCacheService } from '@kudoengineer/http';

Then:

private readonly cache =
  inject(KudoCacheService);

Clear all cache:

this.cache.clear();

Invalidate a URL:

this.cache.invalidate('/users');

Check cache:

this.cache.has('GET:/users');

Get cache size:

this.cache.size();

🔁 Request Deduplication

Request deduplication prevents multiple identical GET requests from being sent simultaneously.

Enable it:

this.http.get('/users', {
  deduplicate: true,
});

If multiple components request:

this.http.get('/users', {
  deduplicate: true,
});

at the same time, the requests can share the same in-flight observable instead of creating unnecessary duplicate network calls.

Deduplication is intended for GET requests.


📶 Angular Signals HTTP Resource

Modern Angular applications can use the Signals-based HTTP resource API.

Inject:

import { KudoHttpResourceService } from '@kudoengineer/http';
private readonly resource =
  inject(KudoHttpResourceService);

Create a resource:

usersResource = this.resource.create(() => this.http.get<User[]>('/users'));

Execute:

this.usersResource.execute();

📊 Signals

The resource provides:

usersResource.data();
usersResource.loading();
usersResource.success();
usersResource.error();
usersResource.status();

🧩 Angular Template Example

@if (usersResource.loading()) {
<p>Loading users...</p>
} @if (usersResource.error()) {
<p>{{ usersResource.error()?.message }}</p>
} @if (usersResource.success()) {
<p>Users loaded successfully.</p>
} @for ( user of usersResource.data() ?? []; track user.id ) {
<p>{{ user.name }}</p>
}

🔄 Reset Resource

this.usersResource.reset();

This resets:

  • data
  • loading
  • success
  • error
  • status

🧹 Destroy Resource

this.usersResource.destroy();

This unsubscribes from the active request.


⚙️ Interceptor Configuration

All built-in interceptors can be configured:

provideKudoHttpInterceptors({
  auth: true,
  error: true,
  retry: true,
  cache: true,
  logging: false,
  requestId: true,
  deduplication: true,
});

🎛️ Disable Interceptors

For example, disable logging:

provideKudoHttpInterceptors({
  logging: false,
});

Disable retry:

provideKudoHttpInterceptors({
  retry: false,
});

Disable caching:

provideKudoHttpInterceptors({
  cache: false,
});

🏗️ Recommended Production Setup

import { ApplicationConfig } from '@angular/core';

import {
  provideKudoHttp,
  provideKudoHttpAuth,
  provideKudoHttpInterceptors,
} from '@kudoengineer/http';

const tokenProvider = {
  getAccessToken: () => {
    return localStorage.getItem('access_token');
  },
};

export const appConfig: ApplicationConfig = {
  providers: [
    provideKudoHttp({
      baseUrl: 'https://api.example.com',

      timeout: 30000,

      retry: {
        enabled: true,
        count: 3,
        delay: 500,
        maxDelay: 5000,
      },

      onError: (error) => {
        console.error('[API Error]', error);
      },
    }),

    provideKudoHttpAuth(tokenProvider, {
      excludedUrls: ['/auth/login', '/auth/register'],
    }),

    provideKudoHttpInterceptors({
      auth: true,
      error: true,
      retry: true,
      cache: true,
      logging: false,
      requestId: true,
      deduplication: true,
    }),
  ],
};

🧱 Architecture

@kudoengineer/http
│
├── core
│   ├── KudoHttpService
│   ├── KudoHttpResource
│   ├── HttpRequest
│   ├── HttpResponse
│   └── HttpError
│
├── config
│   ├── HttpConfig
│   ├── Defaults
│   └── Providers
│
├── auth
│   ├── TokenProvider
│   ├── AuthConfig
│   └── AuthInterceptor
│
├── interceptors
│   ├── Auth
│   ├── Error
│   ├── Retry
│   ├── Cache
│   ├── Logging
│   ├── Request ID
│   └── Deduplication
│
├── cache
│   ├── CacheStore
│   ├── CacheService
│   ├── CacheEntry
│   └── CachePolicy
│
├── retry
│   ├── RetryPolicy
│   ├── Backoff
│   └── RetryContext
│
└── utils
    ├── Headers
    ├── Params
    └── Request ID

📚 API Overview

KudoHttpService

get()
post()
put()
patch()
delete()
head()
options()

KudoHttpResourceService

create()

KudoHttpResource

data
loading
success
error
status
execute()
reset()
destroy()

KudoCacheService

clear()
invalidate()
delete()
has()
size()
keys()

KudoCacheStore

get()
set()
delete()
clear()
has()
size()
keys()
deleteByUrl()

🔒 Security Recommendations

For production applications:

  • Never log access tokens.
  • Never enable body/header logging without reviewing sensitive data.
  • Prefer secure token storage appropriate to your application's security model.
  • Use HTTPS for production APIs.
  • Avoid caching sensitive responses unless explicitly required.
  • Configure authentication exclusions carefully.
  • Use request IDs for backend traceability.

🌐 Links

KudoEngineer

https://kudoengineer.com

NPM Package

https://www.npmjs.com/package/@kudoengineer/http


👨‍💻 Author

Satendra Rajput

Software Engineer | Angular | Java | Spring Boot

Website:

https://kudoengineer.com


📄 License

MIT License

Copyright © Satendra Rajput


⭐ Support

If @kudoengineer/http helps your Angular project, consider giving the project a ⭐ and sharing it with other Angular developers.

Built with ❤️ by KudoEngineer