Use this command to install truyenazz-crawler with WinGet:
winget install --id=Kurokeita.TruyenazzCrawler -e
truyenazz-crawler is a Rust command-line crawler designed to download chapters from truyenazz.me novels as clean local HTML files and build them into an EPUB format with metadata, cover images, and embedded font support.
Key Features:
Crawl individual chapters or entire ranges from a truyenazz novel URL.
Automatically detect the latest available chapter when --end is omitted.
Save chapters in a per-novel output directory as clean HTML files.
Build an EPUB from crawled chapters or existing chapter folders.
Support for sequential or parallel downloading with multiple workers.
Customize behavior for handling existing chapter files (ask, skip, overwrite).
Interactive TUI wizard for streamlined crawling and EPUB building.
Cross-platform support through GitHub Actions, including Linux, Windows, macOS Intel, and macOS ARM.
Audience & Benefit:
Ideal for Rust developers and users familiar with command-line tools who want to organize, preserve, and read their favorite truyenazz novels offline in a reader-friendly format without ads or external dependencies. The EPUB output ensures compatibility with most e-book readers and devices while maintaining high-quality formatting with optional embedded fonts.
The tool can be installed via winget for ease of use on supported platforms.
README
novel-downloader
Rust command-line crawler for Vietnamese novel sites. It downloads chapter
ranges as clean local HTML files and can package those saved chapters into an
EPUB with metadata, cover image, and embedded font support.
Supported hosts:
metruyenhotvn.com
metruyenhotne.com
khodocsach.com
xtruyen.vn
You never pick a source. Pass a novel URL and the host decides which adapter
handles it: the metruyenhot hosts are scraped from HTML, khodocsach.com is
read through its JSON API, and xtruyen.vn is scraped from HTML whose chapter
text arrives encoded and is decoded locally. URLs from any other host are
rejected with a clear error before any network fetch. The hidden
--allow-any-host flag bypasses the check for local mock fixtures and
integration tests; it is not intended for normal use.
A khodocsach chapter costs two requests, a short-lived ticket followed by the
chapter content, so its adapter does more work per chapter than the metruyenhot
scraper does. Interrupting a run costs nothing on any host: re-run the same
command and already-saved chapters are skipped.
xtruyen.vn enforces a request limit per client address, so its adapter sets
the pace: at most 2 concurrent requests with half a second between them, and
a refusal is retried after however long the site says to wait. That is applied
whatever --workers and --delay say, and the run tells you when it overrides
either. The interactive wizard does not ask for those two values for
this host at all, since the answers would be discarded, and the confirmation
screen shows the pacing the run will actually use. Expect roughly two minutes
for a 200-chapter novel. Chapter numbering follows the site's own reading order
rather than the number printed on each chapter, because some chapters are
published as extensions of an earlier one (chuong-12-1 following
chuong-12); on a novel like that, --start and --end count positions, so
they can drift from the labels the site shows.
Features
Crawl one chapter or a chapter range from a supported novel URL.
Automatically discover the latest available chapter when --end is omitted.
Save chapters under a per-novel output directory as chapter_NNNN.html.
Build an EPUB from newly crawled chapters or from an existing chapter folder.
Run sequentially or with multiple download workers.
Choose how to handle existing chapter files: ask, skip, or overwrite.
cargo run -- "https://metruyenhotvn.com/your-novel" --epub-only --chapter-dir output/your_novel
Embed a custom font in the EPUB:
cargo run -- "https://metruyenhotvn.com/your-novel" --epub --font-path /path/to/font.ttf
CLI Options
novel-downloader [OPTIONS] [BASE_URL]
Options:
--start Start chapter number, inclusive
--end End chapter number, inclusive
--output-root Root output directory [default: output]
--delay Extra pause after each chapter is written [default: 0.5]
--workers Number of concurrent download workers [default: 1]
--epub Build an EPUB after crawling
--epub-only Build an EPUB from existing saved chapter files
--chapter-dir Existing chapter directory for --epub-only
--font-path Font file to embed instead of the bundled font
--if-exists ask, skip, or overwrite [default: ask]
--fast-skip Skip remote checks when the destination file already exists
-i, --interactive Launch the interactive TUI
-h, --help Show help
-V, --version Show version
--workers > 1 requires --if-exists skip or --if-exists overwrite, because
interactive per-file prompts are only safe in the sequential path.
--delay is your own pause after each chapter is written, and it applies to
every worker. Each source additionally enforces a minimum spacing between
requests that --delay cannot lower, and may cap --workers; the run tells you
when that happens.
How It Works
flowchart TD
A["User runs novel-downloader"] --> B["cli parses arguments"]
B --> C{"interactive or missing URL?"}
C -->|yes| D["ui wizard collects plan"]
C -->|no| E["build non-interactive plan"]
D --> F["registry resolves the host to a SiteAdapter"]
E --> F
F --> G["adapter fetches metadata and the chapter index"]
G --> H["selected chapter refs"]
H --> I{"mode"}
I -->|crawl| J["runner walks the chapter refs"]
I -->|crawl + epub| J
I -->|epub only| N["use existing chapter directory"]
J --> K{"workers"}
K -->|1| L["sequential runner"]
K -->|many| M["parallel runner"]
L --> O["adapter fetches one chapter"]
M --> O
O --> Q["write chapter_NNNN.html"]
Q --> R{"build EPUB?"}
N --> R
R -->|no| S["finish"]
R -->|yes| T["epub reads saved chapters"]
T --> U["download the cover, embed the font"]
U --> V["package EPUB zip"]
V --> S
Code Layout
src/cli.rs: argument parsing and option validation.
src/bin/novel-downloader.rs: process entry point and top-level orchestration.
src/source/: the site seam. The SiteAdapter trait, the shared Novel, ChapterRef, RatePolicy and SourceError types, the host registry, and one module per site (metruyenhot scrapes HTML, khodocsach reads a JSON API, xtruyen scrapes HTML and decodes an encoded chapter payload).
src/crawler/: the on-disk chapter document format, plus the fetch-write-skip flow and its existing-file policy.
src/runner.rs: sequential and parallel chapter runners with progress events, concurrency clamping, and rate-policy pacing.