A fully typed, zero-dependency client for the AniList GraphQL API.
Supports Node.js and modern browsers.
- Zero dependencies — uses the native
fetchAPI - Universal — Node.js ≥ 20, and modern browsers
- Dual format — ships ESM + CJS with full
.d.tsdeclarations - LRU cache with TTL, stale-while-revalidate, and hit/miss stats
- Rate-limit protection with exponential backoff, retries, and custom strategies
- Request deduplication — concurrent identical queries share a single in-flight request
- Automatic batching (DataLoader) — groups rapid, individual
getMedia(id)calls within a 50ms window into a single batch query, saving API limits. - Batch queries — manually fetch up to 50 media, characters, or staff in a single API call
- Auto-pagination — async iterator that yields items across all pages
- AbortSignal support — cancel globally or per-request via
withSignal() - Injectable logger — plug in
console, pino, winston, or any compatible logger - Redis-ready — swap the in-memory cache with the built-in
RedisCacheadapter
npm install ani-client
# pnpm
pnpm add ani-client
# yarn
yarn add ani-clientimport { AniListClient, MediaType } from "ani-client";
const client = new AniListClient();
// Fetch an anime by AniList ID
const bebop = await client.getMedia(1);
console.log(bebop.title.romaji); // "Cowboy Bebop"
// Search with filters
const results = await client.searchMedia({
query: "Naruto",
type: MediaType.ANIME,
genres: ["Action"],
perPage: 10,
});For full API reference, configuration options, caching, rate limiting, and advanced usage guides, please visit the official documentation:
| Runtime | Version |
|---|---|
| Node.js | ≥ 22.13.0 |
| Browsers | fetch + AbortController required |
Contributions are welcome! Before opening an issue or a pull request, please read:
Note:
ani-clientis an unofficial, community-driven tool. It is not affiliated with, endorsed by, or associated with AniList or AniChart in any way.