A typed TypeScript wrapper for the AniList GraphQL API.
@api-wrappers/anilist-wrapper is a typed AniList GraphQL wrapper for anime,
manga, characters, staff, users, media lists, and raw GraphQL escape hatches.
It gives TypeScript and Bun or Node.js apps dedicated services for common
AniList workflows while keeping direct GraphQL access available when AniList
supports a field the wrapper has not modeled yet.
npm install @api-wrappers/anilist-wrapper
# or
bun add @api-wrappers/anilist-wrapper
# or
pnpm add @api-wrappers/anilist-wrapper
# or
yarn add @api-wrappers/anilist-wrapperimport { Anilist } from "@api-wrappers/anilist-wrapper";
const anilist = new Anilist();
const anime = await anilist.anime.getAnimeById(16498);
console.log(anime.Media?.title?.userPreferred);- Typed services cover common AniList resources without repeating operation strings in every app.
- Generated GraphQL schema and operation types are exported from the package.
- The client sets the AniList endpoint, JSON headers, optional bearer auth, and retry behavior for AniList rate-limit responses.
- Shared fragments keep anime, manga, staff, character, user, and list response shapes consistent across convenience methods.
- The raw GraphQL service stays available for new AniList fields, one-off queries, or app-specific projections.
Use graphql-request or another generic GraphQL client if all you need is a
small transport layer and you want to own every query string yourself.
Use this wrapper when you want AniList-specific service methods, generated
operation types, documented examples, built-in auth header setup, and a stable
set of convenience APIs for anime, manga, characters, staff, users, and media
lists. You can still run custom operations through anilist.graphql.request.
import { Anilist } from "@api-wrappers/anilist-wrapper";
const anilist = new Anilist();Most public anime, manga, character, staff, and username-based user reads work without a token.
import { Anilist } from "@api-wrappers/anilist-wrapper";
const anilist = new Anilist(process.env.ANILIST_TOKEN);Use an authenticated client for private user data, favorites, and media list mutations.
const anime = await anilist.anime.getAnimeById(16498);
console.log(anime.Media?.title?.userPreferred);
console.log(anime.Media?.siteUrl);const results = await anilist.anime.getAnimeBySearch("Frieren", 1, 5);
for (const media of results.Page?.media ?? []) {
console.log(media?.title?.userPreferred, media?.startDate?.year);
}const manga = await anilist.manga.getMangaById(30013);
console.log(manga.Media?.title?.userPreferred);
console.log(manga.Media?.chapters);const character = await anilist.character.getCharacterById(1);
console.log(character.Character?.name?.full);
console.log(character.Character?.siteUrl);const staff = await anilist.staff.getStaffById(95269);
console.log(staff.Staff?.name?.full);
console.log(staff.Staff?.primaryOccupations?.filter(Boolean).join(", "));import { MediaListStatus } from "@api-wrappers/anilist-wrapper";
const list = await anilist.user.getUserAnimeListByUsername(
"example_user",
MediaListStatus.Current,
);
for (const group of list.MediaListCollection?.lists ?? []) {
console.log(group?.entries?.length ?? 0);
}import { Anilist, MediaListStatus } from "@api-wrappers/anilist-wrapper";
const anilist = new Anilist(process.env.ANILIST_TOKEN);
const saved = await anilist.mediaList.saveEntry({
mediaId: 16498,
status: MediaListStatus.Current,
progress: 1,
score: 8,
});
console.log(saved.SaveMediaListEntry?.id);saveEntry creates or updates the authenticated user's media list entry. AniList
requires a valid access token for this mutation.
import { Anilist, gql } from "@api-wrappers/anilist-wrapper";
const anilist = new Anilist();
const data = await anilist.graphql.request<{
GenreCollection: Array<string | null> | null;
}>(gql`
query Genres {
GenreCollection
}
`);
console.log(data.GenreCollection);- Anime tracker: search anime, read details, and save watch progress.
- Manga tracker: search manga, inspect chapters or volumes, and update reading progress.
- User list importer: read public anime or manga lists by username and map list entries into your app.
- Recommendation app: combine media details, genres, tags, rankings, relations, and AniList recommendations.
- AniList dashboard: render user profile data, statistics, current lists, and quick links to AniList pages.
| Property | Use it for |
|---|---|
anilist.anime |
Anime lookup, search, trending, popular, genre, relations, characters, staff, recommendations, favorites |
anilist.manga |
Manga lookup, search, trending, popular, genre, relations, characters, staff, recommendations, favorites |
anilist.character |
Character lookup, birthdays, favorites |
anilist.staff |
Staff lookup, birthdays, favorites |
anilist.user |
User profiles, public lists by username, authenticated list/stat queries by user ID |
anilist.media |
Generic anime/manga media lookup and list access |
anilist.mediaList |
Media list entry lookup, save, and delete |
anilist.graphql |
Any AniList GraphQL query or mutation |
The package ships ESM, CommonJS, and TypeScript declaration output from
dist/. It is developed and tested with Bun, and it can be used from modern
Node.js runtimes that support the package exports field and fetch-compatible
HTTP behavior through @api-wrappers/api-core.
GraphQL schema and operation types are generated into src/__generated__/ from
codegen.yml, the query documents in src/queries/, and the fragments in
src/fragments/. Do not edit generated files by hand.
Run bun run codegen when you add or change GraphQL operations, fragments, or
schema-driven types. The codegen step fetches the AniList schema, writes the
generated files, then runs scripts/patch-codegen.ts so the generated SDK uses
the package's @api-wrappers/api-core GraphQL client shape.
- Documentation home
- Practical examples
- Authentication guide
- API reference
- Runnable examples
- Contribution ideas
Run examples directly from this repo:
bun examples/basic-anime.ts
bun examples/manga-workflow.ts
bun examples/characters-and-staff.ts
bun examples/raw-graphql.ts
ANILIST_TOKEN=... ANILIST_USERNAME=... bun examples/authenticated-user.tsbun install
bun run check
bun run typecheck
bun test
bun run build
bun run verifybun test calls the live AniList API. bun run verify runs the local checks,
typecheck, build, and Bun pack dry-run.
Use bun run codegen only when GraphQL operations, fragments, or generated
types need to be refreshed.
Maintainers use Changesets for releases. Add a changeset for user-facing changes
with bun run changeset; merging the generated version PR on main publishes
to npm and creates GitHub release notes through the release workflow.
Issues and pull requests are welcome. Read CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SECURITY.md before contributing.
MIT