A lightweight, zero-dependency HTTP client library for making type-safe API requests in JavaScript/TypeScript.
- Type-Safe: Full TypeScript support with comprehensive type inference
- Zero Dependencies: Lightweight and fast
- Flexible Configuration: Highly customizable request handling
- Retry Mechanism: Built-in request retry logic
- Caching Support: Optional response caching for GET requests
- Multiple Content Types: Support for JSON, Form, Text, Blob, Multipart, XML, and HTML
npm install @thatguyjamal/type-fetch
# or
yarn add @thatguyjamal/type-fetch
# or
pnpm add @thatguyjamal/type-fetch
# or
bun add @thatguyjamal/type-fetch- TypeScript:
>=4.5.0 - Node.js:
>=16.0.0 - Browsers: All modern browsers (Chrome, Firefox, Safari, Edge)
import { TFetchClient } from '@thatguyjamal/type-fetch';
// Create a client instance
const client = new TFetchClient();
// GET Request
interface User {
id: number;
name: string;
}
const { data, error } = await client.get<User>('https://api.example.com/users/1');
if (error) {
console.error('Request failed:', error);
} else {
console.log('User:', data);
}
// POST Request
const { data: newUser, error: postError } = await client.post<User>(
'https://api.example.com/users',
{ type: 'json', data: { name: 'John Doe' } }
);const client = new TFetchClient({
// Enable debug logging
debug: true,
// Default headers for all requests
headers: { 'Authorization': 'Bearer token' },
// Retry mechanism
retry: {
count: 3, // Number of retry attempts
delay: 1000, // Delay between retries (ms)
onRetry: () => { // Optional callback on each retry
console.log('Retrying request...');
}
},
// Caching for GET requests
cache: {
enabled: true, // Enable caching
maxAge: 5 * 60000, // Cache expiration (5 minutes)
maxCachedEntries: 100 // Maximum number of cached entries
},
// Customize DELETE request handling
deleteHandling: 'status' // 'empty' | 'status' | 'json'
});Type-fetch provides a powerful and flexible caching mechanism for all HTTP methods:
// Global cache configuration
const client = new TFetchClient({
cache: {
enabled: true, // Enable caching globally
maxAge: 5 * 60 * 1000, // 5 minutes default cache time
maxCachedEntries: 1000 // Maximum number of cache entries
}
});
// Per-request cache configuration
const result = await client.get<User>('/users/1', {
cache: {
enabled: true, // Override global cache setting
maxAge: 10 * 60 * 1000 // Custom cache time for this request
}
});- Support for caching all HTTP methods (GET, POST, PUT, DELETE, etc.)
- Intelligent cache key generation based on URL, method, headers, and body
- Configurable global and per-request cache settings
- Automatic cache cleanup to prevent memory overflow
// Create a new user with caching
const result = await client.post<User>('/users',
{ type: 'json', data: { name: 'John Doe', email: '[email protected]' } },
{
cache: {
enabled: true, // Cache the POST request
maxAge: 15 * 60 * 1000 // Cache for 15 minutes
}
}
);// Update user profile with caching
const result = await client.patch<User>('/users/123',
{ type: 'json', data: { name: 'Jane Smith' } },
{
cache: {
enabled: true, // Cache the PATCH request
maxAge: 10 * 60 * 1000 // Cache for 10 minutes
}
}
);get<T>(): Retrieve resourcespost<T>(): Create new resourcesput<T>(): Update existing resourcespatch<T>(): Partially update resourcesdelete<T>(): Remove resourceshead<T>(): Retrieve headers only
Supported content types for requests:
json: JSON dataform: URL-encoded form datatext: Plain textblob: Binary datamultipart: Form data with filesxml: XML documentshtml: HTML documents
// JSON
await client.post('https://api.example.com/users', {
type: 'json',
data: { name: 'John' }
});
// Multipart Form Data
const formData = new FormData();
formData.append('file', fileBlob, 'avatar.png');
await client.post('https://api.example.com/upload', {
type: 'multipart',
data: formData
});The library provides a robust TFetchError with additional context:
interface Result<T> {
data: T | null;
error: TFetchError | null;
}
// Error properties
error.message // Error description
error.statusCode // HTTP status codeCustomize how DELETE requests are handled:
// 'empty' (default): Returns { data: null, error: null }
// 'status': Returns { data: statusCode, error: null }
// 'json': Attempts to parse JSON response
const client = new TFetchClient({ deleteHandling: 'status' });For the full license text, see the LICENSE file in the repository.
If you encounter any issues or have questions, please open an issue on GitHub.
Found a bug? Want to contribute? Please open an issue or submit a pull request on GitHub.