Skip to main content

Overview

@kreisler/anime-api is a comprehensive TypeScript library for scraping anime information from AnimeFLV and integrating with Jikan (MyAnimeList) API. It provides methods to search, browse, and retrieve detailed anime information including episodes, characters, and download links. Package: @kreisler/anime-api
Version: 2.0.0
License: MIT

Installation

npm install @kreisler/anime-api

Quick Start

import {
  search,
  getAnimeInfo,
  latestAnimeAdded,
  latestEpisodesAdded
} from '@kreisler/anime-api';

// Search for anime
const results = await search('tokyo ghoul');

// Get anime details
const info = await getAnimeInfo('anime/5226/tokyo-ghoul', 'Tokyo Ghoul');

// Get latest episodes
const episodes = await latestEpisodesAdded();

Core Functions

Searches for anime by query string.
query
string
required
Search query (anime title or keywords).
return
Promise<AnimeSearchResult[]>
Array of anime search results.
const results = await search('naruto');

results.forEach(anime => {
  console.log(`${anime.title} - ${anime.type}`);
  console.log(`Episodes: ${anime.episodes?.length}`);
});

getAnimeInfo()

Retrieves detailed information about a specific anime.
id
string
required
Anime ID from AnimeFLV (e.g., “anime/5226/tokyo-ghoul”).
title
string
required
Anime title for fetching additional info from Jikan.
return
Promise<AnimeDetailedInfo[]>
Array containing detailed anime information.
const [anime] = await getAnimeInfo(
  'anime/5226/tokyo-ghoul',
  'Tokyo Ghoul'
);

console.log('Title:', anime.title);
console.log('Synopsis:', anime.synopsis);
console.log('Episodes:', anime.episodes?.length);
console.log('Characters:', anime.charactersList?.length);

latestAnimeAdded()

Retrieves the latest anime added to AnimeFLV.
return
Promise<AnimeSearchResult[]>
Array of recently added anime.
const latest = await latestAnimeAdded();

console.log('Latest anime:');
latest.forEach(anime => {
  console.log(`- ${anime.title} (${anime.type})`);
});

latestEpisodesAdded()

Retrieves the latest episodes added to AnimeFLV.
return
Promise<LatestEpisode[]>
Array of recently added episodes.
const episodes = await latestEpisodesAdded();

episodes.forEach(ep => {
  console.log(`${ep.title} - Episode ${ep.episode}`);
  console.log(`Servers: ${ep.servers?.length}`);
});

getAnimeServers()

Retrieves streaming server information for a specific episode.
id
string
required
Episode ID (e.g., “ver/5226/tokyo-ghoul-1”).
return
Promise<IServersData[]>
Array of available servers.
const servers = await getAnimeServers('ver/5226/tokyo-ghoul-1');

servers.forEach(server => {
  console.log(`${server.server}: ${server.code}`);
  console.log(`Ads: ${server.ads}, Mobile: ${server.allow_mobile}`);
});

downloadLinksByEpsId()

Retrieves download links for a specific episode.
id
string
required
Episode ID.
return
Promise<IDownloadLinksByEpsId[]>
Array of download links.
const downloads = await downloadLinksByEpsId('ver/5226/tokyo-ghoul-1');

downloads.forEach(link => {
  console.log(`${link.server}: ${link.url}`);
});

Browse Functions

tv()

Browses TV anime with pagination and sorting.
order
'updated' | 'added'
required
Sort order (by update date or added date).
page
string
required
Page number as string (e.g., “1”, “2”).
return
Promise<AnimeSearchResult[]>
Array of TV anime.
const tvAnime = await tv('updated', '1');
console.log(`Found ${tvAnime.length} TV anime`);

movies()

Browses anime movies.
order
'updated' | 'added'
required
Sort order.
page
string
required
Page number.
return
Promise<AnimeSearchResult[]>
Array of anime movies.
const movieList = await movies('added', '1');

ova()

Browses OVA anime.
order
'updated' | 'added'
required
Sort order.
page
string
required
Page number.
return
Promise<AnimeSearchResult[]>
Array of OVA anime.
const ovaList = await ova('updated', '1');

special()

Browses special episodes and anime.
order
'updated' | 'added'
required
Sort order.
page
string
required
Page number.
return
Promise<AnimeSearchResult[]>
Array of special anime.
const specials = await special('added', '1');

animeByState()

Browses anime filtered by airing status.
state
number
required
Status code (1 = Currently Airing, 2 = Finished Airing, 3 = Not Yet Aired).
order
'updated' | 'added'
required
Sort order.
page
string
required
Page number.
return
Promise<AnimeSearchResult[]>
Array of anime matching the status.
// Get currently airing anime
const airing = await animeByState(1, 'updated', '1');

// Get finished anime
const finished = await animeByState(2, 'updated', '1');

animeByGenres()

Browses anime filtered by genre.
genre
string
required
Genre slug (e.g., ‘comedia’, ‘accion’, ‘romance’).
order
'updated' | 'added'
required
Sort order.
page
string
required
Page number.
return
Promise<AnimeSearchResult[]>
Array of anime in the specified genre.
const comedyAnime = await animeByGenres('comedia', 'updated', '1');
const actionAnime = await animeByGenres('accion', 'added', '1');

Additional Information Functions

getAnimeVideoPromo()

Retrieves promotional videos for an anime from MyAnimeList.
title
string
required
Anime title to search on MyAnimeList.
return
Promise<PromoVideo[] | null>
Array of promotional videos or null if not found.
const promos = await getAnimeVideoPromo('Tokyo Ghoul');

if (promos) {
  promos.forEach(promo => {
    console.log(`${promo.title}: ${promo.videoURL}`);
  });
}

getAnimeCharacters()

Retrieves character information from MyAnimeList.
title
string
required
Anime title.
return
Promise<Character[] | null>
Array of characters or null if not found.
const characters = await getAnimeCharacters('Tokyo Ghoul');

if (characters) {
  characters.forEach(({ character }) => {
    console.log(`${character.name} (${character.role})`);
  });
}

Interfaces

AnimeEpisode

Represents an anime episode.
episode
string
Episode number.
id
string
Episode ID for streaming/downloading.
imagePreview
string
Episode thumbnail URL.
nextEpisodeDate
string
Release date of next episode (for ongoing anime).

AnimeExtraInfo

Additional anime information from MyAnimeList.
titleJapanese
string
Japanese title.
source
string
Source material (Manga, Light Novel, Original, etc.).
totalEpisodes
number
Total number of episodes.
status
string
Airing status.
aired
object
Airing dates.
duration
string
Episode duration.
rank
number
MyAnimeList rank.
popularity
number
Popularity rank.
members
number
Number of members who added it.
favorites
number
Number of users who favorited it.
premiered
string
Premiere season and year.
broadcast
string
Broadcast time.
producers
object
Production companies.
licensors
object
Licensing companies.
studios
object
Animation studios.
openingThemes
string[]
Opening theme songs.
endingThemes
string[]
Ending theme songs.

IFlvFiltros

Filter options for browsing anime.
genre[]
string
Genre filter (e.g., ‘comedia’, ‘accion’).
year[]
number
Year filter.
type[]
'tv' | 'movie'
Type filter.
status[]
number
Status filter (1-3).
order
'updated' | 'added'
Sort order.
page
string
Page number.

Usage Examples

Search and Display Anime

import { search } from '@kreisler/anime-api';

const query = 'one piece';
const results = await search(query);

results.forEach(anime => {
  console.log('\n---');
  console.log('Title:', anime.title);
  console.log('Type:', anime.type);
  console.log('Rating:', anime.rating);
  console.log('Genres:', anime.genres?.join(', '));
  console.log('Episodes:', anime.episodes?.length);
});

Get Complete Anime Information

import { search, getAnimeInfo } from '@kreisler/anime-api';

// First search for the anime
const [result] = await search('death note');

if (result) {
  // Then get detailed information
  const [details] = await getAnimeInfo(result.id!, result.title!);
  
  console.log('Title:', details.title);
  console.log('Synopsis:', details.synopsis);
  console.log('\nExtra Info from MyAnimeList:');
  console.log('Japanese Title:', details.moreInfo?.titleJapanese);
  console.log('Total Episodes:', details.moreInfo?.totalEpisodes);
  console.log('Status:', details.moreInfo?.status);
  console.log('Rank:', details.moreInfo?.rank);
  console.log('Studios:', details.moreInfo?.studios?.names.join(', '));
  
  console.log('\nCharacters:');
  details.charactersList?.slice(0, 5).forEach(({ character }) => {
    console.log(`- ${character.name} (${character.role})`);
  });
}

Browse Latest Episodes

import { latestEpisodesAdded, getAnimeServers } from '@kreisler/anime-api';

const episodes = await latestEpisodesAdded();

console.log('Latest Episodes:');

for (const ep of episodes.slice(0, 5)) {
  console.log(`\n${ep.title} - Episode ${ep.episode}`);
  
  // Get available servers
  if (ep.id) {
    const servers = await getAnimeServers(ep.id);
    console.log('Available servers:', servers.map(s => s.server).join(', '));
  }
}

Filter by Genre and Status

import { animeByGenres, animeByState } from '@kreisler/anime-api';

// Get currently airing action anime
const airingAction = await animeByGenres('accion', 'updated', '1');

console.log('Currently Airing Action Anime:');
airingAction.forEach(anime => {
  console.log(`- ${anime.title}`);
});

// Get finished comedy anime
const finishedComedy = await animeByState(2, 'updated', '1');
console.log('\nFinished Anime:');
finishedComedy.slice(0, 10).forEach(anime => {
  console.log(`- ${anime.title}`);
});
import {
  latestEpisodesAdded,
  downloadLinksByEpsId
} from '@kreisler/anime-api';

const [episode] = await latestEpisodesAdded();

if (episode.id) {
  const downloads = await downloadLinksByEpsId(episode.id);
  
  console.log(`Download links for ${episode.title} - Episode ${episode.episode}:`);
  downloads.forEach(link => {
    console.log(`${link.server}: ${link.url}`);
  });
}

Build a Complete Anime Database

import {
  tv,
  movies,
  ova,
  getAnimeInfo
} from '@kreisler/anime-api';

const database = [];

// Get TV anime from multiple pages
for (let page = 1; page <= 3; page++) {
  const anime = await tv('updated', String(page));
  database.push(...anime);
}

// Get movies
const movieList = await movies('updated', '1');
database.push(...movieList);

// Get OVAs
const ovaList = await ova('updated', '1');
database.push(...ovaList);

console.log(`Total anime in database: ${database.length}`);

// Get detailed info for each
for (const anime of database.slice(0, 5)) {
  const [details] = await getAnimeInfo(anime.id!, anime.title!);
  console.log(`Processed: ${details.title}`);
}

Helper Utilities

imageUrlToBase64()

Internal utility that converts image URLs to base64 format.
url
string
required
Image URL to convert.
return
Promise<string>
Base64 encoded image string.

Constants

URLS

Object containing all API endpoints.
BASE_URL
string
AnimeFLV base URL.
SEARCH_URL
string
Search endpoint.
BROWSE_URL
string
Browse/filter endpoint.
ANIME_VIDEO_URL
string
Video/episode endpoint.
BASE_EPISODE_IMG_URL
string
Episode thumbnail base URL.
BASE_JIKA_URL
string
Jikan API search endpoint.
BASE_JIKA_API
string
Jikan API base URL.

Error Handling

All functions handle errors gracefully and return null or empty arrays when data cannot be fetched:
try {
  const results = await search('nonexistent anime');
  if (results.length === 0) {
    console.log('No results found');
  }
} catch (error) {
  console.error('Search failed:', error);
}

Rate Limiting

Be mindful of rate limits when making multiple requests:
// Add delays between requests
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

for (const anime of animeList) {
  const info = await getAnimeInfo(anime.id, anime.title);
  await delay(1000); // Wait 1 second between requests
}

Dependencies

  • cheerio - HTML parsing and scraping
  • cheerio-tableparser - Table parsing for download links
  • cloudscraper - HTTP client with Cloudflare bypass
  • urldecode - URL decoding utilities
  • image-to-base64 - Image conversion

Build docs developers (and LLMs) love