文書 · Documentation
AniLink
A typed TypeScript client for the AniList GraphQL and MyAnimeList REST APIs. One class, two isolated provider surfaces, normalized errors, retries, pacing, and a generated operation reference.
One client, two surfaces
Typed from install to response
Construct once with per-provider credentials. Each surface is fully typed — variables in, responses out — and they never share a transport credential.
import { AniLink } from "anilink-api-wrapper";
// One client, two isolated provider surfaces.
const aniLink = new AniLink({
anilist: { authToken: process.env.ANILIST_TOKEN },
mal: { accessToken: process.env.MAL_TOKEN },
});
// AniList — typed GraphQL, no token needed for public reads.
const anime = await aniLink.anilist.query.media({
id: 21,
type: "ANIME",
});
console.log(anime.media?.title?.romaji); // → "One Piece"
// MyAnimeList — typed REST, public fields need no token.
const mal = await aniLink.mal.anime.get(21, {
fields: ["id", "title", "main_picture"],
});
console.log(mal.title);Why AniLink
The plumbing, done once
Calling AniList or MAL directly means hand-rolling HTTP, GraphQL documents, OAuth flows, retry logic, and rate-limit handling. AniLink does that once, with types.
Typed operations
Every query, page query, and mutation ships with typed variables and a typed response, generated from the provider schemas. No hand-written GraphQL shapes.
Normalized errors
Provider failures become AniLinkError subclasses with stable code values. Classify failures by code, not by parsing message strings.
Resilience built in
Retries with jittered backoff, optional rate-limit pacing, and an optional circuit breaker — identical behavior on both providers.
Provider isolation
Credentials and transport settings are scoped per provider slot. A MAL token is never sent to AniList, and vice versa.
Observability hooks
onRequestStart, onSuccess, onRetry, and onError fire at every stage of the request lifecycle. Instrument calls without wrapping a single method.
Cancellation & timeouts
Pass an AbortSignal or a per-request timeout and the transport cancels in flight, releases the attempt, and surfaces a typed cancellation error.
Two providers, one client
AniList & MyAnimeList
The two surfaces share a transport layer — timeouts, retries, pacing, the circuit breaker, hooks, error normalization — but never share credentials.
The documentation
Where to start reading
The docs are organized as a single reading path. Begin with the start guides, move through the core transport concepts, then branch into provider-specific guides and the generated operation reference.
Start here
Getting oriented
Core concepts
The transport layer
Cookbook
Patterns & recipes
AniList · GraphQL
AniList guides
MyAnimeList · REST
MAL guides
Ready to build?
Install the package and make your first typed call in under a minute.