npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@genga-movie/aniwatch

v1.0.1

Published

A Node.js library providing high-level APIs to scrape anime information from multiple sources — inspired by @consumet/extensions.

Downloads

46

Readme

@genga-movie/aniwatch

npm version License: MIT TypeScript

A Node.js library providing high-level APIs to scrape anime information from multiple sources — inspired by @consumet/extensions.

⚠️ Disclaimer: This is an unofficial scraper package. Content belongs to its respective owners. For personal/educational use only.

Table of Contents


Installation

npm install @genga-movie/aniwatch
# or
yarn add @genga-movie/aniwatch
# or
pnpm add @genga-movie/aniwatch

Requirements: Node.js >= 18


Quick Start

// ESM
import { ANIME, ExtensionsError } from "@genga-movie/aniwatch";

// CommonJS
const { ANIME, ExtensionsError } = require("@genga-movie/aniwatch");

const hianime = new ANIME.HiAnime();

// Search for anime
const results = await hianime.search("steins gate");
console.log(results.animes[0]);
// { id: 'steinsgate-3', name: "Steins;Gate", poster: '...', episodes: { sub: 24, dub: 24 } }

// Get streaming links
const sources = await hianime.getEpisodeSources(
  "steinsgate-3?ep=230",
  "hd-1",
  "sub"
);
console.log(sources.sources[0].url); // .m3u8 HLS stream URL

Providers

ANIME.HiAnime

Scrapes aniwatchtv.to — one of the most complete anime streaming sites.

import { ANIME } from "@genga-movie/aniwatch";

const hianime = new ANIME.HiAnime();

getHomePage()

Get the home page with spotlight, trending, top 10, and more.

const data = await hianime.getHomePage();

Response:

{
  genres: string[];
  spotlightAnimes: SpotlightAnime[];     // featured animes (ranked 1–10)
  trendingAnimes: TrendingAnime[];
  top10Animes: { today: Top10Anime[]; week: Top10Anime[]; month: Top10Anime[] };
  latestEpisodeAnimes: AnimeCard[];
  topUpcomingAnimes: AnimeCard[];
  topAiringAnimes: AnimeCard[];
  mostPopularAnimes: AnimeCard[];
  mostFavoriteAnimes: AnimeCard[];
  latestCompletedAnimes: AnimeCard[];
}

getAZList(sortOption, page?)

Get anime sorted alphabetically.

| Parameter | Type | Default | Description | |---|---|---|---| | sortOption | AZListSortOption | "all" | Letter, "0-9", "all", "other" | | page | number | 1 | Page number |

const data = await hianime.getAZList("a", 1);
// data.animes, data.totalPages, data.hasNextPage

getQtipInfo(animeId)

Get quick tooltip popup info for an anime.

const data = await hianime.getQtipInfo("one-piece-100");
// data.name, data.malscore, data.genres, data.status, data.description

getInfo(animeId)

Get full, detailed information about an anime.

const data = await hianime.getInfo("attack-on-titan-112");
// data.anime.info — name, poster, description, stats
// data.anime.moreInfo — aired, genres, status, studios
// data.seasons — list of seasons
// data.recommendedAnimes, data.relatedAnimes

search(query, page?, filters?)

Search for anime by name with optional advanced filters.

| Parameter | Type | Default | Description | |---|---|---|---| | query | string | — | Search query | | page | number | 1 | Page number | | filters | SearchFilters | {} | Advanced filters |

Available filters:

| Filter | Example | |---|---| | type | "movie", "tv", "ova" | | status | "finished-airing", "airing" | | rated | "pg-13", "r+" | | score | "good", "very-good" | | season | "spring", "summer", "fall", "winter" | | language | "sub", "dub", "sub-&-dub" | | sort | "score", "recently-added" | | genres | "action,adventure" | | start_date | "2020-4-0" (yyyy-mm-dd, 0 = omit) |

// Basic
const data = await hianime.search("one piece");

// Advanced
const data = await hianime.search("girls", 1, {
  genres: "action,adventure",
  type: "movie",
  sort: "score",
  season: "spring",
  language: "dub",
  status: "finished-airing",
});

searchSuggestions(query)

Get search autocomplete suggestions.

const data = await hianime.searchSuggestions("monster");
// data.suggestions — [{ id, name, poster, jname, moreInfo }]

getCategoryAnime(category, page?)

Get anime by category.

Available categories: "most-favorite", "most-popular", "subbed-anime", "dubbed-anime", "recently-updated", "recently-added", "top-upcoming", "top-airing", "movie", "special", "ova", "ona", "tv", "completed"

const data = await hianime.getCategoryAnime("tv", 2);
// data.animes, data.category, data.genres, data.top10Animes

getGenreAnime(genreName, page?)

Get anime by genre.

const data = await hianime.getGenreAnime("shounen", 1);
const data = await hianime.getGenreAnime("isekai", 2);

getProducerAnimes(producerName, page?)

Get anime by producer/studio.

const data = await hianime.getProducerAnimes("toei-animation", 1);
const data = await hianime.getProducerAnimes("mappa", 2);

getEstimatedSchedule(date, tzOffset?)

Get the estimated airing schedule for a date.

| Parameter | Type | Default | Description | |---|---|---|---| | date | string | — | "yyyy-mm-dd" format | | tzOffset | number | -330 | Timezone offset in minutes |

const today = new Date().toISOString().split("T")[0];
const data = await hianime.getEstimatedSchedule(today);
// data.scheduledAnimes — [{ id, name, jname, time, airingTimestamp, secondsUntilAiring }]

getEpisodes(animeId)

Get the full episode list for an anime.

const data = await hianime.getEpisodes("steinsgate-3");
// data.totalEpisodes → 24
// data.episodes → [{ number, title, episodeId, isFiller }]

getNextEpisodeSchedule(animeId)

Get the next episode airing time.

const data = await hianime.getNextEpisodeSchedule("one-piece-100");
// data.airingTimestamp, data.secondsUntilAiring, data.airingISOTimestamp

getEpisodeServers(episodeId)

Get available streaming servers for an episode.

const data = await hianime.getEpisodeServers("steinsgate-0-92?ep=2055");
// data.sub  → [{ serverId, serverName }]
// data.dub  → [{ serverId, serverName }]
// data.raw  → [{ serverId, serverName }]

getEpisodeSources(episodeId, server?, category?)

Get the streaming source URLs (HLS .m3u8) for an episode.

| Parameter | Type | Default | Description | |---|---|---|---| | episodeId | string | — | Episode ID (e.g. "steinsgate-3?ep=230") | | server | AnimeServer | "hd-1" | Server name | | category | EpisodeCategory | "sub" | "sub" | "dub" | "raw" |

Available servers: "hd-1", "hd-2", "megacloud", "streamsb", "streamtape", "vidstreaming"

const data = await hianime.getEpisodeSources(
  "steinsgate-3?ep=230",
  "hd-1",
  "sub"
);
// data.sources[0].url  → HLS .m3u8 stream URL
// data.subtitles       → [{ lang, url }]
// data.anilistID, data.malID

Error Handling

All methods throw ExtensionsError on failure:

import { ANIME, ExtensionsError } from "@genga-movie/aniwatch";

const hianime = new ANIME.HiAnime();

try {
  const data = await hianime.getInfo("invalid-id-99999");
} catch (err) {
  if (err instanceof ExtensionsError) {
    console.error(err.status);   // HTTP status code (e.g. 404, 500)
    console.error(err.message);  // Human-readable message
    console.error(err.provider); // Provider ID that threw (e.g. "hianime")
  }
}

TypeScript Support

This package ships with full TypeScript types. All types are exported from the main entry:

import type {
  AnimeCard,
  HomePage,
  SpotlightAnime,
  AnimeAboutInfo,
  AnimeEpisodes,
  EpisodeSources,
  SearchFilters,
  AnimeServer,
  EpisodeCategory,
  AZListSortOption,
  AnimeCategory,
} from "@genga-movie/aniwatch";

Building Your Own Provider

Extend BaseProvider to add a new scraping source:

import {
  BaseProvider,
  HttpClient,
  ExtensionsError,
} from "@genga-movie/aniwatch";

export class MyProvider extends BaseProvider {
  readonly id = "myprovider";
  readonly name = "My Custom Provider";
  readonly baseUrl = "https://example.com";
  readonly version = "1.0.0";
  readonly isWorking = true;

  private http = new HttpClient(this.id, { baseURL: this.baseUrl });

  async search(query: string) {
    const { data: html } = await this.http.get(`/search?q=${query}`);
    // parse with cheerio...
    return { results: [] };
  }
}

Development

# Clone and navigate to the package directory
cd package

# Install dependencies
npm install

# Build (ESM + CJS + types)
npm run build

# Watch mode (ESM only)
npm run dev

# Run tests (live integration tests)
npm test

# Run the example script
npm run example

# Type check only
npm run typecheck

License

MIT © solo12345689