Skip to content
AniLink

Introduction

AniLink is a typed TypeScript client for two anime-database APIs. One class, AniLink, composes two independent provider surfaces:

ProviderProtocolNamespaceWhat it offers
AniListGraphQLaniLink.anilistQueries, page queries, mutations, pagination helpers, custom(), data helpers
MyAnimeList (MAL)RESTaniLink.malanime.get and user.me REST reads with field selection

The two surfaces share a transport layer (timeouts, retries, pacing, circuit breaker, hooks, error normalization) but never share credentials. A MAL access token is never sent to AniList. An AniList bearer token is never sent to MAL.

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 operation has typed variables and a typed response, generated from the provider schemas.
  • Normalized errors. Provider failures become AniLinkError subclasses with stable code values, so you classify failures without parsing messages.
  • Resilience built in. Retries with jittered backoff, optional rate-limit pacing, and an optional circuit breaker work identically on both providers.
  • Provider isolation. Credentials and transport settings are scoped per provider slot.

When to use custom()

anilist.custom() (AniList only) sends a raw GraphQL document you write yourself. Use it when you need a field combination the typed operations do not expose. MAL has no equivalent — the MAL surface is fixed REST operations.

How to choose a provider

  • Need rich anime/manga metadata, lists, activity, or social features? AniList — it has the large GraphQL surface.
  • Need data from a user's MyAnimeList account or MAL anime details? MAL — currently anime.get and user.me only.
  • Need both? Compose them in one client and keep each provider's credentials in its own slot. See Provider configuration.

Where to go next

AniLink — typed AniList & MyAnimeList client for TypeScript.