aniwatch
aniwatch copied to clipboard
anime scraper package for hianime.to
Aniwatch
[!IMPORTANT]
- This package is just an unofficial package for hianimez.to and is in no other way officially related to the same.
- The content that this package provides is not mine, nor is it hosted by me. These belong to their respective owners. This package just demonstrates how to build a package that scrapes websites and uses their content.
Table of Contents
-
Quick Start
- Installation
- Example Usage
- Documentation
-
- getHomePage
- getAZList
- getQtipInfo
- getAnimeAboutInfo
- getAnimeSearchResults
- getAnimeSearchSuggestion
- getProducerAnimes
- getGenreAnime
- getAnimeCategory
- getEstimatedSchedule
- getNextEpisodeSchedule
- getAnimeEpisodes
- getEpisodeServers
- getAnimeEpisodeSources
- Development
- Thanks
- Support
- License
- Contributors
- Star History
Quick start
Installation
To use aniwatch package in your project, run:
pnpm add aniwatch
# or "yarn add aniwatch"
# or "npm install aniwatch"
Example usage
Example - getting information about an anime by providing it's unique anime id, using anime Steins;Gate with steinsgate-3 unique anime id as an example.
import { HiAnime, HiAnimeError } from "aniwatch";
const hianime = new HiAnime.Scraper();
try {
const data: HiAnime.ScrapedAnimeAboutInfo = await hianime.getInfo(
"steinsgate-3"
);
console.log(data);
} catch (err) {
console.error(err instanceof HiAnimeError, err);
}
getHomePage
getHomePageSample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getHomePage()
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
genres: ["Action", "Cars", "Adventure", ...],
latestEpisodeAnimes: [
{
id: string,
name: string,
poster: string,
type: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
spotlightAnimes: [
{
id: string,
name: string,
jname: string,
poster: string,
description: string,
rank: number,
otherInfo: string[],
episodes: {
sub: number,
dub: number,
},
},
{...},
],
top10Animes: {
today: [
{
episodes: {
sub: number,
dub: number,
},
id: string,
name: string,
poster: string,
rank: number
},
{...},
],
month: [...],
week: [...]
},
topAiringAnimes: [
{
id: string,
name: string,
jname: string,
poster: string,
},
{...},
],
topUpcomingAnimes: [
{
id: string,
name: string,
poster: string,
duration: string,
type: string,
rating: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
trendingAnimes: [
{
id: string,
name: string,
poster: string,
rank: number,
},
{...},
],
mostPopularAnimes: [
{
id: string,
name: string,
poster: string,
type: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
mostFavoriteAnimes: [
{
id: string,
name: string,
poster: string,
type: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
latestCompletedAnimes: [
{
id: string,
name: string,
poster: string,
type: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
}
๐ผ Back to Top
getAZList
getAZListParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
sortOption |
string | The az-list sort option. Possible values include: "all", "other", "0-9" and all english alphabets . | Yes | -- |
page |
number | The page number of the result. | No | 1 |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getAZList("0-9", 1)
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
sortOption: "0-9",
animes: [
{
id: string,
name: string,
jname: string,
poster: string,
duration: string,
type: string,
rating: string,
episodes: {
sub: number ,
dub: number
}
},
{...}
],
totalPages: 1,
currentPage: 1,
hasNextPage: false
}
๐ผ Back to Top
getQtipInfo
getQtipInfoParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
animeId |
string | The unique anime id (in kebab case). | Yes | -- |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getQtipInfo("one-piece-100")
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
anime: {
id: "one-piece-100",
name: "One Piece",
malscore: string,
quality: string,
episodes: {
sub: number,
dub: number
},
type: string,
description: string,
jname: string,
synonyms: string,
aired: string,
status: string,
genres: ["Action", "Adventure", "Comedy", "Drama", "Fantasy", "Shounen", "Drama", "Fantasy", "Shounen", "Fantasy", "Shounen", "Shounen", "Super Power"]
}
}
๐ผ Back to Top
getAnimeAboutInfo
getAnimeAboutInfoParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
animeId |
string | The unique anime id (in kebab case). | Yes | -- |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getInfo("steinsgate-3")
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
anime: [
info: {
id: string,
name: string,
poster: string,
description: string,
stats: {
rating: string,
quality: string,
episodes: {
sub: number,
dub: number
},
type: string,
duration: string
},
promotionalVideos: [
{
title: string | undefined,
source: string | undefined,
thumbnail: string | undefined
},
{...},
],
characterVoiceActor: [
{
character: {
id: string,
poster: string,
name: string,
cast: string
},
voiceActor: {
id: string,
poster: string,
name: string,
cast: string
}
},
{...},
]
}
moreInfo: {
aired: string,
genres: ["Action", "Mystery", ...],
status: string,
studios: string,
duration: string
...
}
],
mostPopularAnimes: [
{
episodes: {
sub: number,
dub: number,
},
id: string,
jname: string,
name: string,
poster: string,
type: string
},
{...},
],
recommendedAnimes: [
{
id: string,
name: string,
poster: string,
duration: string,
type: string,
rating: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
relatedAnimes: [
{
id: string,
name: string,
poster: string,
duration: string,
type: string,
rating: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
seasons: [
{
id: string,
name: string,
title: string,
poster: string,
isCurrent: boolean
},
{...}
]
}
๐ผ Back to Top
getAnimeSearchResults
getAnimeSearchResultsParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
q |
string | The search query, i.e. the title of the item you are looking for. | Yes | -- |
page |
number | The page number of the result. | No | 1 |
type |
string | Type of the anime. eg: movie |
No | -- |
status |
string | Status of the anime. eg: finished-airing |
No | -- |
rated |
string | Rating of the anime. eg: r+ or pg-13 |
No | -- |
score |
string | Score of the anime. eg: good or very-good |
No | -- |
season |
string | Season of the aired anime. eg: spring |
No | -- |
language |
string | Language category of the anime. eg: sub or sub-&-dub |
No | -- |
start_date |
string | Start date of the anime(yyyy-mm-dd). eg: 2014-10-2 |
No | -- |
end_date |
string | End date of the anime(yyyy-mm-dd). eg: 2010-12-4 |
No | -- |
sort |
string | Order of sorting the anime result. eg: recently-added |
No | -- |
genres |
string | Genre of the anime, separated by commas. eg: isekai,shounen |
No | -- |
[!TIP]
For both
start_dateandend_date, year must be mentioned. If you wanna omit date or month specify0instead. Eg: omitting date -> 2014-10-0, omitting month -> 2014-0-12, omitting both -> 2014-0-0
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.search("monster", 1, {
genres: "seinen,psychological",
})
.then((data) => {
console.log(data);
})
.catch((err) => {
console.error(err);
});
Response Schema
{
animes: [
{
id: string,
name: string,
poster: string,
duration: string,
type: string,
rating: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
mostPopularAnimes: [
{
episodes: {
sub: number,
dub: number,
},
id: string,
jname: string,
name: string,
poster: string,
type: string
},
{...},
],
currentPage: 1,
totalPages: 1,
hasNextPage: false,
searchQuery: string,
searchFilters: {
[filter_name]: [filter_value]
...
}
}
๐ผ Back to Top
getAnimeSearchSuggestion
getAnimeSearchSuggestionParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
q |
string | The search suggestion query. | Yes | -- |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.searchSuggestions("one piece")
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
suggestions: [
{
id: string,
name: string,
poster: string,
jname: string,
moreInfo: ["Mar 4, 2000", "Movie", "50m"]
},
{...},
],
}
๐ผ Back to Top
getProducerAnimes
getProducerAnimesParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
name |
string | The name of anime producer (in kebab case). | Yes | |
page |
number | The page number of the result. | No | 1 |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getProducerAnimes("toei-animation", 2)
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
producerName: "Toei Animation Anime",
animes: [
{
id: string,
name: string,
poster: string,
duration: string,
type: string,
rating: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
top10Animes: {
today: [
{
episodes: {
sub: number,
dub: number,
},
id: string,
name: string,
poster: string,
rank: number
},
{...},
],
month: [...],
week: [...]
},
topAiringAnimes: [
{
episodes: {
sub: number,
dub: number,
},
id: string,
jname: string,
name: string,
poster: string,
type: string
},
{...},
],
currentPage: 2,
totalPages: 11,
hasNextPage: true,
}
๐ผ Back to Top
getGenreAnime
getGenreAnimeParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
name |
string | The name of anime genre (in kebab case). | Yes | -- |
page |
number | The page number of the result. | No | 1 |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getGenreAnime("shounen", 2)
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
genreName: "Shounen Anime",
animes: [
{
id: string,
name: string,
poster: string,
duration: string,
type: string,
rating: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
genres: ["Action", "Cars", "Adventure", ...],
topAiringAnimes: [
{
episodes: {
sub: number,
dub: number,
},
id: string,
jname: string,
name: string,
poster: string,
type: string
},
{...},
],
currentPage: 2,
totalPages: 38,
hasNextPage: true
}
๐ผ Back to Top
getAnimeCategory
getAnimeCategoryParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
category |
string | The category of anime. | Yes | -- |
page |
number | The page number of the result. | No | 1 |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getCategoryAnime("subbed-anime")
.then((data) => console.log(data))
.catch((err) => console.error(err));
// categories ->
// "most-favorite", "most-popular", "subbed-anime", "dubbed-anime",
// "recently-updated", "recently-added", "top-upcoming", "top-airing",
// "movie", "special", "ova", "ona", "tv", "completed"
Response Schema
{
category: "TV Series Anime",
animes: [
{
id: string,
name: string,
poster: string,
duration: string,
type: string,
rating: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
genres: ["Action", "Cars", "Adventure", ...],
top10Animes: {
today: [
{
episodes: {
sub: number,
dub: number,
},
id: string,
name: string,
poster: string,
rank: number
},
{...},
],
month: [...],
week: [...]
},
currentPage: 2,
totalPages: 100,
hasNextPage: true
}
๐ผ Back to Top
getEstimatedSchedule
getEstimatedScheduleParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
date (yyyy-mm-dd) |
string | The date of the desired schedule. (months & days must have 2 digits) | Yes | -- |
tzOffset |
number | The timezone offset in minutes (defaults to -330 i.e. IST) | No | -330 |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
const timezoneOffset = -330; // IST offset in minutes
hianime
.getEstimatedSchedule("2025-06-09", timezoneOffset)
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
scheduledAnimes: [
{
id: string,
time: string, // 24 hours format
name: string,
jname: string,
airingTimestamp: number,
secondsUntilAiring: number
},
{...}
]
}
๐ผ Back to Top
getNextEpisodeSchedule
getNextEpisodeScheduleParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
animeId |
string | The unique anime id (in kebab case). | Yes | -- |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getNextEpisodeSchedule("one-piece-100")
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
airingISOTimestamp: string | null,
airingTimestamp: number | null,
secondsUntilAiring: number | null
}
๐ผ Back to Top
getAnimeEpisodes
getAnimeEpisodesParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
animeId |
string | The unique anime id. | Yes | -- |
Sample Usage
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getEpisodes("steinsgate-3")
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
totalEpisodes: 24,
episodes: [
{
number: 1,
isFiller: false,
title: "Turning Point",
episodeId: "steinsgate-3?ep=213"
},
{...}
]
}
๐ผ Back to Top
getEpisodeServers
getEpisodeServersParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
episodeId |
string | The unique episode id. | Yes | -- |
Request sample
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getEpisodeServers("steinsgate-0-92?ep=2055")
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
episodeId: "steinsgate-0-92?ep=2055",
episodeNo: 5,
sub: [
{
serverId: 4,
serverName: "vidstreaming",
},
{...}
],
dub: [
{
serverId: 1,
serverName: "megacloud",
},
{...}
],
raw: [
{
serverId: 1,
serverName: "megacloud",
},
{...}
],
}
๐ผ Back to Top
getAnimeEpisodeSources
getAnimeEpisodeSourcesParameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
id |
string | The id of the episode. | Yes | -- |
server |
string | The name of the server. | No | "vidstreaming" |
category |
string | The category of the episode ('sub', 'dub' or 'raw'). | No | "sub" |
Request sample
import { HiAnime } from "aniwatch";
const hianime = new HiAnime.Scraper();
hianime
.getEpisodeSources("steinsgate-3?ep=230", "hd-1", "sub")
.then((data) => console.log(data))
.catch((err) => console.error(err));
Response Schema
{
headers: {
Referer: string,
"User-Agent": string,
...
},
sources: [
{
url: string, // .m3u8 hls streaming file
isM3U8: boolean,
quality?: string,
},
{...}
],
subtitles: [
{
lang: "English",
url: string, // .vtt subtitle file
default: boolean,
},
{...}
],
anilistID: number | null,
malID: number | null,
}
๐ผ Back to Top
Development
Pull requests are always welcome. If you encounter any bug or want to add a new feature to this package, consider creating a new issue. If you wish to contribute to this project, read the CONTRIBUTING.md file.
Contributors
Thanks to the following people for keeping this project alive and relevant.
Thanks
Support
Don't forget to leave a star ๐. You can also follow me on X (Twitter) @riteshgsh.
License
This project is licensed under the MIT License - see the LICENSE file for more details.