Skip to main content

Nyora logo

Nyora — the manga reader SDK for Python

Build your own manga, manhwa & manhua reader in ~10 lines.

nyora is the official Python SDK for Nyora — a self-contained client that gives you 390 live, health-checked sources across 40 languages through one typed API: search, browse, read chapters, download .cbz, and sync a library across devices. pip install nyora bundles the parser engine and launches it locally on demand (auto-downloads a JRE if you don't have Java) — no server, no scraper to maintain. You're reading in 60 seconds.

PyPI version Python versions License: Apache 2.0

In one line: Nyora is the programmatic, cross-platform Tachiyomi / Mihon / Kotatsu alternative — a manga API and reader SDK you can import. If you're building a manga reader, a scanlation bot, a downloader, or a library manager in Python, this is the fastest way to get hundreds of working sources without writing or maintaining a single scraper.


The terminal reader

A dense, keyboard-driven manga reader in your terminal — a redesigned first-run setup, live theming, and an interface available in ~40 languages. Launch it with a bare nyora.

Nyora TUI — sources grouped by language, keyboard-driven

Branded welcome / sign-in or continue as guest First-run setup: app language, colour theme, source languages
Language navigator — jump to any source language Colour-theme picker — 10 schemes, light and dark

Available in ~40 languages

The whole interface — onboarding, navigation and the reader — localises into ~40 languages (English fallback for anything untranslated), including right-to-left scripts. Change it anytime from Settings (,).

Onboarding in Japanese
日本語 — onboarding
Settings in Russian, Totoro theme
Русский — settings (Totoro theme)
Keyboard help in Arabic, right-to-left
العربية — help (RTL)

Table of contents


Why Nyora

📚 390 working sources Every source is live health-checked; 570 dead or Cloudflare-walled ones are auto-hidden, so list()/catalog() return only sources that actually work — 390 across 40 languages (289 all-ages, 101 mature).
🌐 One typed API Source, Manga, MangaChapter, MangaPage, MangaDetails dataclasses. Full type hints, py.typed, mypy-clean.
📦 Self-contained Bundles the kotatsu-parsers engine and runs it locally (auto-downloads a JRE if you have no Java). Parsed results, not scraping headaches — nothing to compile, no Node, no server.
🔀 Correct chapter order Built-in next_chapter() / previous_chapter() work on both ascending (MangaDex 0→N) and descending (scanlation N→0) sources — no off-by-one "next goes backwards" bug.
🧰 Batteries included A CLI, an interactive terminal reader (TUI), a .cbz downloader, and cross-device cloud sync — all in one pip install.
Sync & async Use Nyora or AsyncNyora with identical APIs.

Install

pip install nyora           # everything: the library, the CLI, and the terminal reader (TUI)

Requires Python 3.10+. Nothing else to run — the parser engine is bundled and launches locally on demand (a JRE is auto-downloaded if you have no Java). One install ships all three front-ends: import nyora (library), nyora-cli (CLI), and bare nyora (TUI).

Quickstart — a working reader in 10 lines

import nyora

with nyora.Nyora() as client:
    source = client.sources.find("mangadex")           # pick any of 390 sources
    hits = client.manga.search(source.id, "frieren")   # search it
    manga = hits.entries[0]

    details = client.manga.details(source.id, manga.url, title=manga.title)
    first = details.reading_order()[0]                 # earliest chapter, order-safe

    for page in client.manga.pages(source.id, first.url, branch=first.branch):
        print(page.url)                                # image URLs, ready to render

That's a complete read path: source → search → details → chapter → page images. Point an image widget (Pillow, a GUI, a web frontend) at those URLs and you have a reader.

Core concepts

A source exposes manga; a manga has chapters; a chapter has pages. Every step is one call.

Nyora ─┬─ sources   → Source        (a content site: MangaDex, Bato, …)
       ├─ manga     → Manga          (a series: title, cover, authors, tags)
       │             → MangaDetails  (Manga + its MangaChapter list)
       │             → MangaChapter  (id, title, number, url, branch, uploadDate)
       │             → MangaPage      (a single image url)
       ├─ library   → favourites, history, bookmarks (local or synced)
       └─ downloads → offline chapter management

Everything is a plain dataclass — dataclasses.asdict() to serialise, full type hints throughout.

API reference

Client

nyora.Nyora(base_url=None, *, timeout=60.0)      # sync client (context manager)
nyora.AsyncNyora(base_url=None, *, timeout=60.0) # async client, identical API with await

base_url defaults to a bundled engine launched locally; pass a URL (or run nyora config set-url) to use a server instead. Attributes: client.sources, client.manga, client.library, client.downloads. Also client.health().

client.sources

Method Returns Description
list() list[Source] Installed/loaded sources (dead ones hidden).
catalog() list[Source] Every available source (dead ones hidden).
find(query) Source First source whose id or name matches (case-insensitive).
filters(source_id) list[SourceFilter] A source's supported search filters.
refresh() / install(id) / uninstall(id) / pin(id) Manage the loaded set.

client.manga

Method Returns Description
popular(source_id, page=1) SearchPage Popular titles from a source.
latest(source_id, page=1) SearchPage Recently updated titles.
search(source_id, query, page=1) SearchPage Search one source.
global_search(query, *, limit_per_source=8) list[GlobalSearchGroup] Search many sources at once.
details(source_id, url, *, title=None) MangaDetails Full metadata + chapter list.
pages(source_id, chapter_url, *, branch=None) list[MangaPage] A chapter's image pages.
suggestions() / alternatives(title) list[Manga] / list[dict] Recommendations / cross-source matches.

SearchPage has .entries: list[Manga] and .has_next_page: bool for pagination.

Chapter ordering helpers

nyora.next_chapter(chapters, current)       # -> MangaChapter | None
nyora.previous_chapter(chapters, current)   # -> MangaChapter | None
nyora.reading_order(chapters)               # -> list, earliest-first
nyora.chapter_reading_delta(chapters)       # -> +1 (ascending) or -1 (descending)
# convenience methods on MangaDetails:
details.next_chapter(chapter)  /  details.previous_chapter(chapter)  /  details.reading_order()

client.library (local, syncable)

history(), record_history(...), favourites(), toggle_favourite(id), is_favourite(id), bookmarks(), add_bookmark(...), remove_bookmark(...).

Recipes

Browse popular with pagination

page = client.manga.popular(source.id, page=1)
while True:
    for m in page.entries:
        print(m.title)
    if not page.has_next_page:
        break
    page = client.manga.popular(source.id, page=page.number + 1)

Search every source at once

for group in client.manga.global_search("solo leveling"):
    print(group.source.name, "→", [m.title for m in group.entries])

Download a chapter as a .cbz

from nyora.cli import _download_pages
from pathlib import Path

pages = client.manga.pages(source.id, chapter.url, branch=chapter.branch)
_download_pages(pages, Path("solo-leveling-ch1"))

Async

import asyncio, nyora

async def main():
    async with nyora.AsyncNyora() as client:
        src = await client.sources.find("mangadex")
        page = await client.manga.popular(src.id)
        print([m.title for m in page.entries])

asyncio.run(main())

Chapter ordering (ascending vs descending sources)

Different sources return chapters in different orders — MangaDex lists oldest-first (0 → N), many scanlation sites list newest-first (N → 0). A naive chapters[i+1] "next chapter" therefore goes backwards on half of all sources. Nyora detects the direction from the chapter numbers so navigation is always correct:

current = details.chapters[3]
nxt = details.next_chapter(current)      # always the LATER chapter, any source order
prv = details.previous_chapter(current)  # always the EARLIER chapter

Cloud sync — a library across devices

from nyora.sync import NyoraSync

sync = NyoraSync()
sync.sign_in("you@example.com", "password")   # or register(...)
sync.upsert("nyora_favourite", [{ "manga_id": manga.url, "sort_key": 0 }])
favs = sync.select("nyora_favourite")          # syncs across every Nyora app

Same account and library as the Nyora apps on Android, iOS, macOS, Windows, Linux and web.

Command line (nyora-cli)

nyora-cli sources --search mangadex        # list/filter sources
nyora-cli popular  -s MANGADEX             # popular titles
nyora-cli search   -s MANGADEX "frieren"   # search
nyora-cli details  -s MANGADEX <manga-url> # metadata + chapters
nyora-cli pages    -s MANGADEX <chap-url>  # page image URLs
nyora-cli download -s MANGADEX <chap-url>  # save a .cbz
nyora-cli --json popular -s MANGADEX       # machine-readable output

Both nyora and nyora-cli are installed. Add --json to any command for scripting.

Interactive terminal reader (TUI)

pip install "nyora[tui]"
nyora            # launch the full-screen reader — browse, search, read, download

Pick a source → search or browse → open a chapter → page through it, with order-independent next / previous chapter navigation and inline downloads.

How it works

nyora is self-contained. pip install nyora bundles the kotatsu-parsers JVM engine (and auto-downloads a JRE if you don't have Java); Nyora() launches it locally on demand — no server, no Node.js, nothing to compile. Dead and Cloudflare-blocked sources are hidden (a sensible static list by default; run nyora blocklist refresh to health-probe your engine and tailor it), so list()/catalog() return only the ~390 sources that actually work. Prefer a server? Point base_url (or nyora config set-url) at any Nyora helper.

FAQ

How do I build a manga reader in Python? pip install nyora, then search → details → pages (see Quickstart). client.manga.pages(...) returns image URLs you can render in any UI.

What's the best manga API / SDK? Nyora gives you 390 working, health-checked sources across 40 languages behind one typed Python API — no scraper maintenance, plus a CLI, TUI, downloader and cloud sync.

Is this a Tachiyomi / Mihon / Kotatsu alternative? Yes — it's the programmatic one. Those are Android apps; Nyora is an importable SDK (and cross-platform apps) built on the same open-source Kotatsu parser engine.

Do I need to run a server or a JVM? No. The engine is hosted. pip install and go. You can self-host and set base_url.

Manga, manhwa or manhua? All three — the sources cover Japanese, Korean and Chinese comics across 40 languages.

JavaScript / TypeScript? Use the sibling SDK: nyora-sdk.

Ecosystem

License

Apache-2.0. Nyora is built on the open-source Kotatsu parser engine and is not affiliated with Tachiyomi, Mihon or Kotatsu.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nyora-2.1.2.tar.gz (31.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nyora-2.1.2-py3-none-any.whl (30.1 MB view details)

Uploaded Python 3

File details

Details for the file nyora-2.1.2.tar.gz.

File metadata

  • Download URL: nyora-2.1.2.tar.gz
  • Upload date:
  • Size: 31.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nyora-2.1.2.tar.gz
Algorithm Hash digest
SHA256 6df0a63b0c72df9eb00174dd08c8f60e4cb959e5ab6286152e31300bdf615700
MD5 28fac7c67d299f28a105cf1e6c615422
BLAKE2b-256 d440471b0ea9226e6e9a1ad46ef5f1368ee506cc494763ea6a34b0a64bb4b700

See more details on using hashes here.

Provenance

The following attestation bundles were made for nyora-2.1.2.tar.gz:

Publisher: publish.yml on Nyora-Manga/nyora-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nyora-2.1.2-py3-none-any.whl.

File metadata

  • Download URL: nyora-2.1.2-py3-none-any.whl
  • Upload date:
  • Size: 30.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nyora-2.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 27b3b091376b84cb3cfde903ec531659268d284e3317fcf0d0bd920f4d131445
MD5 0887086d9aeb6b30bae2ca53ca5d3cba
BLAKE2b-256 4573ebe29231645f4cbd3d109b39fb48024ee65a5293096c5bdb494528622537

See more details on using hashes here.

Provenance

The following attestation bundles were made for nyora-2.1.2-py3-none-any.whl:

Publisher: publish.yml on Nyora-Manga/nyora-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

2.1.4

2 files

2.1.3

2 files

This release

2.1.2 This release

2 files

2.1.1

2 files

2.1.0

2 files

2.0.3

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page