# TypedFetch > Fetch for humans who have shit to build TypedFetch is a next-generation HTTP client that brings type safety, intelligent error handling, and developer-friendly features to API communication. It eliminates the boilerplate and pain points of traditional fetch/axios approaches while providing a tRPC-like experience that works with any REST API. ## 🚀 Quick Start ```bash npm install typedfetch ``` ```typescript import { createTypedFetch } from 'typedfetch' // Define your API structure const client = createTypedFetch<{ users: { get: (id: string) => User list: () => User[] create: (data: CreateUser) => User } }>({ baseURL: 'https://api.example.com' }) // Use with full type safety const { data, error } = await client.users.get('123') if (error) { // TypeScript knows the error structure! switch (error.type) { case 'not_found': // Handle 404 case 'network': // Handle network error } } // TypeScript knows data is User | undefined ``` ## ✨ Features ### 🔒 Type Safety Without Code Generation - Full TypeScript inference throughout request/response cycle - No more `any` types or manual casting - Compile-time URL validation - Response type discrimination ### 🛡️ Unified Error Handling - Categorized, actionable errors (network, HTTP, parsing, timeout, abort) - Discriminated unions for type-safe error handling - Automatic retry logic with exponential backoff - Circuit breaker pattern for failing endpoints ### 🚀 Zero Boilerplate - Define once, use everywhere - Intelligent defaults - Proxy-based API with dot notation - Auto-injected auth tokens ### ⚡ Built-in Resilience - Request retry with smart conditions - Request deduplication - Multi-tier caching (memory + IndexedDB) - HTTP cache header respect - Offline support ### 🔧 Developer Experience - Setup in <5 minutes - IntelliSense for everything - Clear, actionable error messages - Zero compile step required ## 📚 Documentation ### Basic Usage ```typescript interface User { id: string name: string email: string } interface CreateUserData { name: string email: string } const client = createTypedFetch<{ users: { get: (id: string) => User list: () => User[] create: (data: CreateUserData) => User update: (params: { id: string } & Partial) => User delete: (id: string) => void } }>({ baseURL: 'https://api.example.com', auth: () => getToken(), // Auto-injected timeout: 30000, // Retry configuration retry: { attempts: 3, delay: (attempt) => Math.min(1000 * Math.pow(2, attempt - 1), 10000), condition: (error) => error.retryable }, // Cache configuration cache: { storage: 'both', // memory + IndexedDB ttl: { 'users.list': 300000, // 5 minutes 'users.get': 3600000, // 1 hour } } }) ``` ### Advanced Configuration ```typescript const client = createTypedFetch({ baseURL: process.env.API_URL, // Global interceptors interceptors: { request: [(config) => { config.headers.authorization = `Bearer ${getToken()}` return config }], response: [(response) => { logMetrics(response) return response }] }, // Request deduplication dedupe: { window: 1000, // 1 second key: (config) => `${config.method}:${config.url}` } }) ``` ### Error Handling ```typescript const { data, error, loading } = await client.users.get('123') if (error) { switch (error.type) { case 'http': if (error.status === 404) { console.log('User not found') } else if (error.status >= 500) { console.log('Server error - will retry automatically') } break case 'network': console.log('Network error:', error.message) break case 'timeout': console.log('Request timed out') break case 'parse': console.log('Invalid response format') break case 'validation': console.log('Response validation failed') break case 'abort': console.log('Request was cancelled') break } } ``` ### Transforms & Interceptors ```typescript import { createDateTransform, createCamelCaseTransform, createLoggingInterceptor } from 'typedfetch' // Add request/response transforms client.addRequestTransform(createSnakeCaseTransform()) client.addResponseTransform('users', createDateTransform()) client.addResponseTransform('users', createCamelCaseTransform()) // Add interceptors const logging = createLoggingInterceptor({ logRequests: true, logResponses: true }) client.addRequestInterceptor(logging.request) client.addResponseInterceptor(logging.response) ``` ## 🏗️ Architecture TypedFetch is built with a layered architecture: - **Layer 0**: Core Types & Interfaces - **Layer 1**: Protocol Abstraction (fetch/XHR/Node.js) - **Layer 2**: Request Pipeline (interceptors, transforms) - **Layer 3**: Resilience Core (retry, circuit breaker, deduplication) - **Layer 4**: Cache Management (HTTP headers, LRU, IndexedDB) - **Layer 5**: Developer API (Proxy-based interface) ## 🎯 Why TypedFetch? ### vs Axios - ✅ Type safety without manual interfaces - ✅ Built-in retry, caching, deduplication - ✅ Modern async/await patterns - ✅ Smaller bundle size (<15KB) ### vs tRPC - ✅ Works with any backend (no server changes needed) - ✅ REST API compatibility - ✅ Gradual adoption - ✅ Framework agnostic ### vs React Query/SWR - ✅ Framework agnostic - ✅ Built-in HTTP client - ✅ More control over requests - ✅ Type-safe error handling ## 📦 Bundle Size - Core: <15KB gzipped - Zero runtime dependencies - Tree-shakeable modules - Works without build step ## 🌐 Browser Support - Modern browsers (ES2020+) - Node.js 16+ - Service Worker support - IndexedDB for persistence ## 🤝 Contributing We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. ## 📄 License MIT License - see [LICENSE](LICENSE) for details. ## 🔗 Links - [Documentation](https://typedfetch.dev) - [Examples](./examples) - [GitHub](https://github.com/typedfetch/typedfetch) - [NPM](https://www.npmjs.com/package/typedfetch) --- **TypedFetch**: Because life's too short for `any` types and network errors. 🚀