A lightweight and modern Node.js module for interacting with the AniList GraphQL API to fetch manga and anime data. This package provides a simple, promise-based interface for querying AniList’s extensive database of manga, anime, manhwa, and Korean anime, with support for searching, retrieving by ID, and fetching top or trending content.
- Manga and Anime Support: Query both manga and anime with consistent APIs.
- Pagination: Built-in support for paginated results with customizable page size.
- Comprehensive Data: Retrieve detailed media information, including titles, descriptions, genres, scores, and more.
-
Lightweight: Minimal dependencies (only
axios
) for a lean package. - Error Handling: Robust error handling for API failures and invalid inputs.
- TypeScript Ready: Includes type definitions for TypeScript users (planned for future releases).
Install the package via npm:
npm install @notsopreety/anilist-js
Ensure you have Node.js version >=14
installed.
Here’s a simple example to get you started with searching for anime:
const { searchAnime } = require('@notsopreety/anilist-js');
async function main() {
try {
const result = await searchAnime('Attack on Titan', 1, 5);
console.log('Page Info:', result.pageInfo);
console.log('Results:', result.media);
} catch (error) {
console.error('Error:', error.message);
}
}
main();
The package exposes ten asynchronous functions for querying manga and anime data. All functions return promises and follow a consistent interface.
-
searchManga(search, page = 1, perPage = 10)
: Search manga by title. -
getMangaById(id)
: Retrieve manga details by AniList ID. -
getTop100Manga(page = 1, perPage = 10)
: Fetch top 100 manga, sorted by score. -
getTrendingManga(page = 1, perPage = 10)
: Fetch trending manga. -
getTopManhwa(page = 1, perPage = 10)
: Fetch top Korean manhwa.
-
searchAnime(search, page = 1, perPage = 10)
: Search anime by title. -
getAnimeById(id)
: Retrieve anime details by AniList ID. -
getTop100Anime(page = 1, perPage = 10)
: Fetch top 100 anime, sorted by score. -
getTrendingAnime(page = 1, perPage = 10)
: Fetch trending anime. -
getTopKoreanAnime(page = 1, perPage = 10)
: Fetch top Korean anime.
Most functions (except getMangaById
and getAnimeById
) return a Page
object with:
-
pageInfo
: Pagination details (total
,currentPage
,lastPage
,hasNextPage
,perPage
). -
media
: Array of media objects containing fields likeid
,title
,coverImage
,description
, etc.
The getMangaById
and getAnimeById
functions return a single media object directly.
Each media object includes:
-
id
: Unique AniList ID. -
title
: Object withromaji
,english
, andnative
titles. -
coverImage
: Object withlarge
image URL. -
description
: Plain text description. -
episodes
: Number of episodes (anime-specific, null for manga). -
chapters
: Number of chapters (manga-specific, null for anime). -
volumes
: Number of volumes (manga-specific, null for anime). -
status
: Media status (e.g.,FINISHED
,RELEASING
). -
genres
: Array of genres. -
averageScore
: Average community score (0-100). -
siteUrl
: URL to the media’s AniList page.
const { searchManga } = require('@notsopreety/anilist-js');
async function searchExample() {
try {
const result = await searchManga('One Piece', 1, 10);
console.log(`Total Results: ${result.pageInfo.total}`);
result.media.forEach((manga, index) => {
console.log(`${index + 1}. ${manga.title.english || manga.title.romaji}`);
});
} catch (error) {
console.error('Error:', error.message);
}
}
searchExample();
const { getAnimeById } = require('@notsopreety/anilist-js');
async function idExample() {
try {
const anime = await getAnimeById(21); // Naruto
console.log('Title:', anime.title.english);
console.log('Description:', anime.description);
console.log('Genres:', anime.genres.join(', '));
} catch (error) {
console.error('Error:', error.message);
}
}
idExample();
const { getTop100Manga } = require('@notsopreety/anilist-js');
async function topMangaExample() {
try {
const result = await getTop100Manga(2, 5); // Page 2, 5 items per page
console.log(`Page ${result.pageInfo.currentPage} of ${result.pageInfo.lastPage}`);
result.media.forEach(manga => {
console.log(`${manga.title.english || manga.title.romaji} (Score: ${manga.averageScore})`);
});
} catch (error) {
console.error('Error:', error.message);
}
}
topMangaExample();
The package throws errors for:
- Invalid input (e.g., non-numeric ID, negative page numbers).
- AniList API errors (e.g., rate limits, invalid queries).
- Network issues.
Example of handling errors:
const { getMangaById } = require('@notsopreety/anilist-js');
async function errorExample() {
try {
await getMangaById('invalid'); // Invalid ID
} catch (error) {
console.error('Failed to fetch manga:', error.message);
}
}
errorExample();
Note: AniList enforces rate limits (approximately 90 requests per minute). Handle 429 Too Many Requests
errors by implementing retries or backoff strategies in your application.
-
Node.js:
>=14
-
Dependencies:
axios (^1.7.2)
To contribute or modify the package locally:
-
Clone the repository:
git clone https://github.com/notsopreety/anilist-js.git cd anilist-js
-
Install dependencies:
npm install
-
Test changes:
- Create a test file or use existing examples.
- Run with
node <test-file>.js
.
-
Submit a pull request with your changes.
- Add TypeScript support with type definitions.
- Implement caching options for frequent queries.
- Support additional AniList queries (e.g., characters, staff, user lists).
- Add unit tests with Jest.
- Provide configuration for custom API endpoints or headers.
Contributions are welcome! Please follow these steps:
- Fork the repository.
- Create a feature branch (
git checkout -b feature/your-feature
). - Commit your changes (
git commit -m 'Add your feature'
). - Push to the branch (
git push origin feature/your-feature
). - Open a pull request.
This project is licensed under the MIT License.
- Built using the AniList GraphQL API.
- Powered by axios for HTTP requests.
For questions or support, open an issue on GitHub or contact Samir Thakuri.