Tiny and elegant HTTP client based on the Fetch API
Ky is a lightweight HTTP client library that wraps the native Fetch API with developer-friendly enhancements. Created by Sindre Sorhus, it addresses common pain points when working with Fetch directly: non-2xx responses don't throw errors, there's no built-in retry mechanism, timeouts require manual AbortController setup, and the API can be verbose for common tasks.
The library provides method shortcuts (ky.get(), ky.post(), etc.), automatic JSON parsing, configurable retry logic, and timeout support out of the box. Unlike heavier alternatives like Axios, Ky maintains a minimal footprint at approximately 157KB with zero dependencies, making it ideal for modern web applications where bundle size matters. It works across browsers, Node.js (18+), Deno, and Bun.
With over 5 million weekly downloads, Ky has become a popular choice for developers who want something more ergonomic than raw Fetch but less bloated than traditional HTTP libraries. It's particularly well-suited for SPAs, isomorphic applications, and any project targeting modern JavaScript runtimes. The library includes full TypeScript support with proper type inference, making it a natural fit for type-safe codebases.
Ky offers advanced features like custom instances with ky.create() for maintaining consistent configuration across API calls, request/response hooks for interceptors, and prefix URLs to avoid repeating base endpoints. The retry mechanism is intelligent enough to handle transient failures while respecting HTTP semantics, and the error handling automatically rejects on non-2xx status codes after following redirects.
import ky from 'ky';
// Create API client with defaults
const api = ky.create({
prefixUrl: 'https://jsonplaceholder.typicode.com',
timeout: 10000,
retry: {
limit: 2,
statusCodes: [408, 413, 429, 500, 502, 503, 504]
},
hooks: {
beforeRequest: [
request => {
request.headers.set('X-Request-ID', crypto.randomUUID());
}
],
afterResponse: [
async (request, options, response) => {
if (response.status === 401) {
console.log('Unauthorized, refresh token...');
}
return response;
}
]
}
});
// Type-safe GET request
interface User {
id: number;
name: string;
email: string;
}
const user = await api.get('users/1').json<User>();
console.log(user.name);
// POST with automatic JSON serialization
const newPost = await api.post('posts', {
json: {
title: 'My Post',
body: 'Content here',
userId: 1
}
}).json();
// Error handling
try {
await api.get('users/999999');
} catch (error) {
if (error instanceof ky.HTTPError) {
console.log('Status:', error.response.status);
const errorBody = await error.response.json();
console.log('Error details:', errorBody);
}
}
// Search params and custom headers
const posts = await api.get('posts', {
searchParams: { userId: '1' },
headers: { 'Accept-Language': 'en-US' }
}).json();Building REST API clients: Ky excels at creating typed API clients for SPAs and Node.js applications. Use ky.create() with a prefixUrl to instantiate a client for a specific API, then leverage JSON shortcuts and custom headers for authenticated requests. The automatic retry logic handles transient network failures without additional code.
Server-side data fetching in Next.js/Remix: When fetching data in server components or loaders, Ky provides a cleaner alternative to node-fetch with built-in timeout support and error handling. The consistent API across client and server simplifies isomorphic applications, though you'll need Node.js 18+ for native Fetch support.
Migrating from Axios with smaller bundles: Teams looking to reduce bundle size can replace Axios with Ky for most common use cases. You get automatic JSON transformation, interceptors via hooks, and error handling while cutting significant kilobytes from your production build. The API is similar enough to make migration straightforward.
Third-party API integrations: When integrating external APIs (payment processors, analytics services, cloud providers), Ky's retry logic and timeout configuration make your integration more resilient. Create dedicated instances per service with appropriate headers, timeouts, and retry strategies to handle each API's specific requirements.
Microservices communication: In Node.js microservices architectures, Ky provides a lightweight HTTP client for service-to-service communication. The hooks system allows implementing circuit breakers, request tracing, or logging middleware. The zero-dependency footprint keeps container images small.
npm install kypnpm add kybun add ky