# MeManga **Automatic manga downloader with a desktop app and a command-line interface.** Track manga across 224 scrapers / 319 domains, read downloaded chapters in the built-in reader, and optionally email them to your Kindle. Works offline once chapters are downloaded.

MeManga Library — dark theme grid of manga covers

latest release release downloads Docker pulls platforms MIT license

--- ## Highlights - **Portable desktop app** — extract and run `MeManga.exe` / `MeManga` / `MeManga.app` - **Library tracking** — your read/unread state survives reboots - **Multi-source search** — 15 aggregators selected by default, searched in a fixed order - **Built-in reader** — zoom, fit-to-page, keyboard nav, no external viewer needed - **PDF / EPUB / CBZ / ZIP / JPG / PNG / WEBP** output - **E-Reader delivery** — auto-send chapters by email after download - **Backup sources** — fall back to a second source if the primary stops updating - **Offline-aware** — disables network actions while offline and enables them again when the connection returns - **Command-line interface** — same engine, scriptable, suited to cron jobs and headless servers - **No telemetry, no accounts, no cloud** — everything stays on your machine --- ## Download Release downloads are available for each platform. | OS | File | |---|---| | Windows | [`MeManga-windows-x64.zip`](../../releases/latest) | | macOS (Apple Silicon) | [`MeManga-macos-arm64.zip`](https://github.com/meellm/MeManga/releases/latest) | | macOS (Intel) | [`MeManga-macos-x64.zip`](https://github.com/meellm/MeManga/releases/latest) | | Linux (x86_64) | [`MeManga-linux-x64.tar.gz`](https://github.com/meellm/MeManga/releases/latest) | On Windows the download is a `.zip` — extract it and run `MeManga.exe` from the `MeManga-windows-x64` folder (keep the `_internal` folder next to it). On macOS the download is a `.zip` — unzip it to get `MeManga.app`, then double-click. > **First launch downloads Firefox** (about 80 MB, once). > Playwright uses it for sources that need a browser, such as MangaFire and WeebCentral. > > **Windows SmartScreen** may show a warning the first time, because the Windows > build is not yet code-signed. Download MeManga only from the > [releases page](https://github.com/meellm/MeManga/releases), then choose > **More info → Run anyway** to start it. > > **macOS Gatekeeper** — the Mac app is not code-signed or notarized by Apple (that needs > a paid Apple Developer account), so macOS may refuse to open it after download. > If macOS says "MeManga is damaged and can't be opened" or that it can't verify the > developer, move `MeManga.app` to Applications and run > `xattr -dr com.apple.quarantine /Applications/MeManga.app` once in Terminal. > > **Linux** ships as a `.tar.gz` so the executable bit survives the download — > a bare binary saves as non-executable and won't launch. Extract, then run: > > ```bash > tar xzf MeManga-linux-x64.tar.gz > ./MeManga-linux-x64/MeManga > ``` > > If a file manager still clears the permission, restore it with > `chmod +x MeManga-linux-x64/MeManga`. Each download has a matching `-THIRD_PARTY_NOTICES.txt` on the release page with the licenses of the third-party software it contains. The same file is inside `MeManga.app` (`Contents/Resources/THIRD_PARTY_NOTICES.txt`) and at the top of the Windows and Linux folders. The desktop app bundles Qt, PySide6, Shiboken6 and img2pdf, which are used under the GNU LGPL. The notices also reproduce the licenses of PDFium and the other third-party code built into Qt PDF, which the reader uses for PDF pages. The notices file opens with a section that links the exact source code of the shipped versions and explains how to use modified versions. On Windows and Linux the app is a folder rather than a single compressed file, so these components stay separate files under `_internal` that you can replace; on macOS you rebuild the app from source with the modified component. You can also build from source; see [Build from source](#build-from-source) below. --- # Part 1 — Desktop App ## First five minutes When you open MeManga for the first time: 1. The Library page is empty — click **+ Add manga** in the header. 2. Paste a manga URL from any [supported source](docs/SUPPORTED_SOURCES.md), or click **Search** in the sidebar and type the title. 3. The app remembers what you added, what you've downloaded, and what you've read across restarts and across machines (config lives in your [MeManga config folder](#where-your-data-lives), you can import/export it).

Add Manga dialog

## Library The Library page is the home screen. Cards show the cover, status pill (`READING`, `COMPLETED`, …), an unread badge when there are new chapters, and an in-progress bar for the current chapter you're on.

Library page with mixed manga statuses

- Click a card → **Detail** page (chapter list, status, mode, Kindle toggle) - Right-click → quick actions (mark as read, change status, remove) - Top-right chip row filters by status; the chip count updates live - Keyboard: `Tab` moves to a card, `Enter` or `Space` opens it, and the `Menu` key or `Shift+F10` opens its quick actions (see [Keyboard shortcuts](#keyboard-shortcuts)) ## Reader Click any downloaded chapter on the Detail page to open it in the built-in reader.

Built-in reader showing a chapter

| Key / mouse | Continuous scroll | Single page / Two-page spread | |---|---|---| | `↑ ↓` / scroll wheel | Scroll | Scroll within the page | | `← →` | Pan sideways when zoomed in, otherwise previous / next chapter | Previous / next page | | `Page Up` / `Page Down`, `Space` | Scroll one screen up / down (`Space` scrolls down) | Previous / next page (`Space` turns forward) | | `Home` / `End` | Start / end of the chapter | First / last page | | `P` / `N` | Previous / next chapter | Previous / next chapter | | `+` (or `=`) / `−`, `Ctrl/Cmd + scroll`, pinch | Zoom in / out | Zoom in / out | | `Ctrl/Cmd + 0` | Reset zoom to 100% | Reset zoom to 100% | | `F` | Toggle fit to width | Toggle fit to width | | Click-drag while zoomed | Pan | Pan | | `Esc` | Back to Detail | Back to Detail | Reaching the end of the chapter marks it read, whichever way you get there. `Tab` moves to the reader's buttons; clicking a button or the page keeps these keys working. PDF chapters MeManga wrote show each page's image exactly as stored, at its original resolution. Any other PDF page, such as one with text, drawings, links or other annotations, a rotated or cropped page, or a PDF made by another program, is drawn as a whole page at 150 dpi with Qt PDF, which is part of Qt. Filled-in form fields are drawn too: their appearance is merged into a copy of the page in memory first, and the file itself is never changed. A filled-in field that has no appearance to draw, as in an incomplete form, is not left out silently: its page shows as a page that couldn't be loaded. A page that can't be read shows "Page N couldn't be loaded." in its place. PyMuPDF is not used, even when it is installed. ## Search By default, search covers 15 aggregators: MangaDex, MangaPill, MangaPark, MangaFire, MangaBuddy, WeebCentral, MangaKatana, Asura Scans, Comix, Comick, MangaHub, MangaHere, MangaPanda, MangaHere.onl and MangaTaro. Turn on more sources on the **Sources** page to search more widely; other sources are often slower or have fewer chapters.

Search results for "Blue Lock" with chapter-count chips

Each result row shows the source domain, a `+ Add` button that adds it to your library and, unless chapter counts are turned off, a `47 ch` chip with the number of chapters that source has. Use the chapter count to choose a source. To get that number, the app loads each result's chapter list from its source, for up to 4 results at a time. One chapter list can take several requests: long lists come in pages (MangaDex sends 100 chapters per request), some sources load theirs in a browser, and a request that fails on a busy or flaky connection may be sent again. In the app, a result that fails or shows no chapters is also loaded up to 3 more times over about 30 seconds; `memanga search` loads it once. On a slow or metered connection, turn off **Show chapter counts in search results** in **Settings → Advanced → Network & Privacy**. That switch only affects the desktop app; for the CLI, use `memanga search --no-chips`. ## Downloads The Downloads page shows what's currently downloading and what just finished. Each row has progress, cancel, and "open folder" buttons. Cancel-all drains the queue cleanly.

Downloads page with active + completed rows

If a chapter fails partway through, MeManga retries the failed pages up to 3× with exponential back-off. If pages are still missing, the chapter is **not** marked as downloaded — next "Check" will pick it back up. ## Sources The Sources page shows every supported domain with its last saved health status (latency, last successful check, last error). Toggle individual sources on or off; your selection persists across restarts. A listed source may no longer be reachable.

Sources page with toggle list and health badges

Select **Re-check health** to check every enabled source and update its status. ## Settings - **General** — output format (PDF/EPUB/CBZ/…), download folder, theme, concurrency - **Kindle / Email** — Gmail App Password setup for sending chapters to your Kindle - **Advanced** — fallback-source delay, post-processing, cron, cache management, and **Network & Privacy** (the connection check and MangaDex cover lookup, see the [FAQ](#faq)). The downloaded desktop app can't set up scheduled checks; use `memanga cron install` from the command-line version instead (see [Schedule daily checks](#schedule-daily-checks)).

Settings page — Kindle/Email tab

### Setting up Kindle delivery 1. [Generate a Gmail App Password](https://support.google.com/accounts/answer/185833) (regular passwords won't work). 2. Add your Gmail address to your [Amazon "Approved Personal Document E-mail List"](https://www.amazon.com/hz/mycd/myx#/home/settings/payment). 3. In **Settings → Kindle / Email**, paste your Kindle email, sender Gmail, and the App Password. **Check Login** only signs in to the mail server and sends nothing. **Send Test PDF** emails a one-page test PDF to your Kindle (`memanga config email --send-test` does the same from the command line). The mail server accepting it does not prove delivery: Amazon delivers it only when the sender is on the approved list, so look for "MeManga test document" in your Kindle library after a few minutes. 4. In **Settings → General**, choose **Email (send to Kindle)** and which manga to send: **Only manga I choose** (selected first, so turning email on never sends the whole library) or **Every manga in my library**. A manga you already turned Kindle on or off for keeps that choice. 5. With **Only manga I choose**, turn on **Send to Kindle after download** on the Detail page of each manga to send. With **Every manga**, turn it off for the manga you don't want sent. Only PDF and EPUB are sent to Kindle; CBZ, ZIP and image folders are saved but not sent. PDFs too large for one email (over 18 MB with the default 25 MB email size limit, `email.max_email_mb`) are split automatically and the parts are sent in one mail session; EPUB files can't be split, so sending one that is too large fails with a size warning. See the [Guide](docs/Guide.md#email-size-limit) to match the limit to your mail provider. ## Keyboard shortcuts `Tab` and `Shift+Tab` move between controls, including the Library cards and rows and the theme cards in Settings. The control with keyboard focus gets a ring (a click doesn't leave one on a button). `Enter` or `Space` activates buttons, cards and rows; arrow keys and `Enter` pick an option in a drop-down or menu; `Esc` closes dialogs. `Page Up` and `Page Down` scroll the page. When a page opens from the keyboard, focus moves to its first control, and after a card's quick action it returns to the card. | Key | Action | |---|---| | `Ctrl/Cmd + K` | Go to Search and put the cursor in the search field | | `Ctrl/Cmd + F` | Filter field on Library and Sources (search field on Search) | | `Ctrl/Cmd + ,` | Settings | | `Alt + ←` (`Cmd + [` on macOS) | Detail page: back to Library | | `Menu` / `Shift + F10` | Library card or row: quick actions | The reader's keys are listed under [Reader](#reader). --- # Part 2 — Command-line interface The CLI ships in the source tree (not the release binary). It's the right tool for cron jobs, headless servers, batch operations, and scripting. The desktop app and the CLI share the same config, state, and download files — you can drive your library from both interchangeably. ## Install Install the package with pip (into a virtual environment), then run `setup` once: ```bash python -m pip install "git+https://github.com/meellm/MeManga.git" memanga setup # config file, download folder, browsers memanga --help # every command ``` Installing only installs the package; it never downloads browsers or writes to your config folder. `memanga setup` does that when you run it, and is safe to run again at any time: - creates `config.yaml` with the default settings when there is none (an existing file is never changed) and the download folder, and checks both are writable; - checks that the Playwright Firefox and Chromium builds the scrapers use are installed. Missing builds (several hundred MB) are downloaded after you agree, or without asking with `--install-browsers`. Without a terminal nothing is downloaded unless you pass that flag; `--no-install-browsers` never downloads; - starts each browser headless to make sure it runs. When system libraries are missing it prints the command that installs them (on Debian/Ubuntu `sudo python -m playwright install-deps firefox chromium`); it never runs sudo or a package manager itself. It exits 0 when everything is ready and 1 when something still needs you, so it also works in provisioning scripts: ```bash memanga --config-dir /srv/memanga setup --install-browsers ``` The default install is the CLI only: it does not pull in PySide6 or any other GUI package, so it suits servers, containers, a Raspberry Pi or a cron job. To run the desktop app from a pip install, add the `gui` extra, which installs PySide6 and enables `memanga --gui` and the `memanga-gui` command. Put `memanga[gui] @` in front of the `git+` URL of the install command above, or run this in a clone of the repository: ```bash python -m pip install ".[gui]" memanga-gui ``` Without the extra, `memanga --gui` and `memanga-gui` exit with that install command instead of starting. The release downloads already include everything. From a clone, the bootstrap script creates a venv and installs everything, including system packages: ```bash git clone https://github.com/meellm/MeManga.git cd MeManga python scripts/bootstrap.py # creates a venv + installs everything ``` The CLI lives at `python -m memanga` once the venv is active. On Windows, prefer: ```cmd .\scripts\windows\setup.bat .\scripts\windows\run.bat ``` On macOS / Linux: ```bash ./scripts/run.sh ``` ## Docker The Docker image packages the CLI and Playwright Firefox runtime for headless servers, NAS boxes, Raspberry Pi systems, and cron-style automation. It does **not** include PySide6 or any other GUI runtime; `memanga --gui` and `memanga-gui` exit with an error there. ```bash docker build -t memanga:cli . docker run --rm memanga:cli --help ``` Release tags publish the official image to Docker Hub and GitHub Container Registry: ```bash docker pull meellm/memanga:latest docker run --rm meellm/memanga:latest --help docker pull ghcr.io/meellm/memanga:latest docker run --rm ghcr.io/meellm/memanga:latest --help ``` Stable releases are published with `X.Y.Z`, `X.Y`, and `latest` tags; pin to a specific `X.Y.Z` tag for reproducible runs. Build locally for unreleased changes. Persist config/state and downloads with two mounts: ```bash mkdir -p memanga-data/config memanga-data/downloads docker run --rm \ -v "$PWD/memanga-data/config:/home/memanga/.config/memanga" \ -v "$PWD/memanga-data/downloads:/home/memanga/Downloads/MeManga" \ memanga:cli status ``` > The container runs as UID 1000, so bind-mounted directories must be > writable by UID 1000 (`sudo chown -R 1000:1000 memanga-data` if your > host user differs). The Compose setup below uses named volumes and > sidesteps this. Use the included `compose.yaml` for repeated commands: ```bash docker compose build docker compose run --rm memanga list docker compose run --rm memanga check --download docker compose run --rm memanga config set delivery.output_format epub ``` `config set email.app_password -` reads the app password from stdin (pipe it in with `docker compose run --rm -T`), so it never appears in the command line. Without a keyring it is then kept in plain text in the config volume; to keep it out, pass it as a Docker secret instead (see [App password as a Docker secret](docs/Guide.md#app-password-as-a-docker-secret)). For scheduled checks without host cron, start the `scheduler` service. It runs `memanga watch --every 6h --jitter 30m`: a check right away, then one every 6 hours plus up to 30 random minutes, and it restarts with Docker unless you stop it: ```bash docker compose up -d scheduler docker compose logs -f scheduler docker compose stop scheduler ``` Checks never overlap, and other commands (`docker compose run --rm memanga add …`) still work between them. Change the interval in `compose.yaml`; see [Scheduling in Docker](docs/Guide.md#scheduling-in-docker). Or use a host cron job, running Compose from the repository directory: ```cron 0 6 * * * cd /path/to/MeManga && docker compose run --rm memanga check --auto --quiet >> memanga-docker.log 2>&1 ``` ## Commands | Command | Purpose | |---|---| | `list` (`ls`) [--json] | Show every tracked manga with status + chapter counts | | `add` | Add a manga; supports `-t TITLE -u URL [-b BACKUP_URL]` or `-i` interactive | | `remove TITLE` (`rm`) [--yes] [--purge-history] [--keep-files \| --delete-files] | Drop a manga from tracking. History and files are kept unless `--purge-history` / `--delete-files` is given; `--yes` only skips the confirmation | | `edit TITLE …` (`update`) | Edit status (`--status reading` / `on-hold` / `dropped` / `completed`), URL, backup (`--backup` / `--no-backup`), fallback days, title, mode or Kindle toggle; only the given fields change. `set TITLE STATUS` still works but is deprecated and will be removed in the next release | | `check [TITLE] [--dry-run \| --download] [--from N] [--safe]` | Look for new chapters (`TITLE` can also be given as `-t TITLE`). `--dry-run` only lists them; `--download` (aliases `--auto`, `--yes`) downloads without prompting; otherwise it asks on a terminal and downloads nothing without one | | `path TITLE` / `open TITLE` | Print a manga's download folder (only the path, for scripts) or open it in the file manager; a manga with nothing downloaded yet exits `1` | | `failed [list [TARGET]] [--json]` / `failed retry [TARGET]` / `failed clear [TARGET]` | List, re-download or forget failed and partial chapters; TARGET goes after the action and is a title or `#N`, matched like `check TITLE`. `--retry` / `--clear` are aliases of `retry` / `clear` | | `send TARGET CHAPTER... [--dry-run] [--yes]` | Send downloaded chapters to the Kindle (again) from their saved files; several chapters ask first unless `--yes`, `--dry-run` only shows what would be sent | | `send --pending [TARGET] [--list \| --clear]` | Send chapters that were saved but never reached the Kindle again; `--list` only lists them, `--clear` forgets the records (the files stay) | | `status [--json]` | Show config dir, download dir, manga count, last check time | | `setup [--install-browsers \| --no-install-browsers]` | Prepare a first run: create the config file and download folder, check (and with consent download) the Playwright browsers, report missing system libraries. Safe to repeat | | `doctor [--json] [--check NAME] [--smtp] [--launch-browsers]` | Diagnose install, paths, browsers, email, keyring, scheduler and source health | | `config` | Interactive settings editor | | `config show [--json]` / `config get KEY` / `config set KEY VALUE` | Show, read or change settings without prompts; values are checked before saving and the app password stays masked | | `config path` / `config edit` / `config email [--test \| --send-test]` | Print the config file path, open it in `$VISUAL`/`$EDITOR` and check it, show email settings (`--test` only logs in to SMTP; `--send-test` emails a small test PDF to the Kindle) | | `cron install [--time 06:00]` | Schedule a daily `check --auto --quiet` job (`--auto` is an alias of `--download`) | | `cron status` / `cron remove` | Inspect / uninstall the cron job | | `watch [--every 6h] [--jitter 30m]` | Stay in the foreground and run `check --auto --quiet` now and on an interval, one at a time (for Docker; see [Docker](#docker)) | | `sources` | List registered sources and their search status (`--json` for metadata) | | `export FILE` / `import FILE` | Back up or restore your library + state as JSON (`-` for stdout/stdin; `import --dry-run` previews, `--replace` asks unless `--yes`) | | `tui` | Launch the in-terminal interactive view | | `completion bash` | Print a bash completion script (see [Shell completion](#shell-completion)) | TITLE matches an exact title (any case) first, then a partial title that fits only one manga; an ambiguous partial title is refused, and a bare number must match a title exactly. Use `"#N"` to pick the Nth manga from `list`. Run any subcommand with `--help` for full flags, and `memanga --version` to print the installed version. ## Common recipes ### Add a manga with a backup source ```bash python -m memanga add \ -t "Blue Lock" \ -u "https://mangapill.com/manga/580/blue-lock" \ -b "https://mangadex.org/title/4141c5dc-c525-4df5-afd7-cc7d192a832f" ``` If MangaPill stops updating, MeManga falls back to MangaDex after `fallback_delay_days` (default 2) — long enough for a slow-translating primary to catch up. ### MangaDex downloads MeManga credits MangaDex and the chapter's scanlation group in the built-in reader and saved chapter metadata (or `Source.txt` for image archives/folders). Original image quality is the default. For smaller Kindle and e-reader downloads, choose **Settings → General → MangaDex Image Quality → Data saver**, or run `python -m memanga config --mangadex-quality data-saver`. Choose `original` to switch back. The choice applies to the next download, not files already saved. Active scanlation group leaders can ask for their group's chapters to be removed by opening an issue with the MangaDex group link. Group IDs accepted from those requests are added to a future release; none are built in yet. To block a group yourself, use the UUID from its MangaDex group page: `python -m memanga config --mangadex-remove-group GROUP_ID`. Checks, downloads and the built-in reader then skip that group's chapters. Delete chapters you already downloaded from that group, including copies sent to an e-reader; MeManga does not delete saved files. Restart the desktop app after changing this setting from the CLI. Blocked IDs appear in `python -m memanga config --show`. MeManga also sends MangaDex@Home the per-image load report it asks clients for (image URL, success, cache hit, size and time) and switches to a new image server after a failed page. ### Backfill an entire series from chapter 1 ```bash python -m memanga check "Blue Lock" --from 1 --download --safe ``` Each browser is already replaced with a fresh one after it has served 20 searches, chapter lists or chapter pages. `--safe` restarts them more often, every 3 chapters, for machines with very little memory. Swap `--download` for `--dry-run` first to see which chapters it would fetch without downloading or changing anything. ### Schedule daily checks ```bash # Linux/macOS — installs a crontab entry python -m memanga cron install --time 06:00 # Windows — register a Task Scheduler entry (run as your user) python -m memanga cron install --time 06:00 ``` ### Retry every failed chapter ```bash python -m memanga failed retry python -m memanga failed retry "Blue Lock" # one manga only ``` `failed` is the safety net for the "downloaded but incomplete" class of errors: the downloader does not mark a chapter complete if any page failed, and tracks the failure so you can batch-retry later. `failed retry` downloads each chapter the same way `check --download` does (backup source, partial-chapter rules, email delivery). `failed clear [TARGET]` forgets the records without downloading. ### Resend chapters that never reached the Kindle ```bash python -m memanga send --pending --list # what is waiting python -m memanga send --pending # send them again ``` When a chapter is saved but the email to the Kindle fails (SMTP outage, wrong password, attachment too large), the chapter stays downloaded and its file is kept. MeManga remembers it until it is sent: `check` and `failed retry` say so and exit `3`, `send --pending [TARGET]` sends it again, and the desktop app shows "Not sent to Kindle" with a Send button in the manga's chapter list. With `delivery.delete_after_send` on, a file is only deleted after it was sent. When a split PDF fails partway, the parts the mail server already accepted are not sent again, unless the file or the Kindle address changed since. `send --pending --clear [TARGET]` forgets the records without sending. To send chapters you already have again, name them: ```bash python -m memanga send "Solo Leveling" 12 --dry-run # which file would go python -m memanga send "Solo Leveling" 12 13 --yes # send both ``` Every chapter must be a downloaded chapter of the manga, or nothing is sent. The saved file is taken from the manga's download folder (a PDF or EPUB is preferred when there are several copies; a chapter still on the `--pending` list uses its recorded file) and nothing is downloaded. A file whose name could also belong to another downloaded chapter (an older name such as `Chapter 2.0` when chapters `2` and `2.0` both exist) is only used when the download history says it is this chapter's. A chapter whose file is missing or can't be told apart, or saved in a format the Kindle doesn't accept (CBZ, ZIP, image folders), is reported while the others are still sent, and the command exits `3`. Sending more than one chapter asks first; `--yes` skips the question and is required in scripts and cron jobs. When the email fails, the chapter goes on the `--pending` list like a failed delivery during `check`; for a split PDF the parts the mail server already accepted are not sent again. ### Diagnose setup problems ```bash python -m memanga doctor ``` `doctor` reports the Python and MeManga versions and how MeManga is installed, then checks the config and state files, download directory, email/keyring setup, the cron or Task Scheduler entry, cached source health, and that the Playwright Firefox and Chromium builds are installed. Nothing touches the network by default; opt in with `--smtp` (log in to your SMTP server) and `--launch-browsers` (start each browser headless). Use `--check NAME` (repeatable) to run only some checks. It exits 0 when no check fails and 1 when one does; `--strict` also fails on warnings. ### Scripting `list`, `status`, `failed`, `search` and `doctor` accept `--json` and then print a single JSON document to stdout with no other output. `list`, `status`, `failed` and `doctor` payloads carry a `schema_version` (currently 1) that changes only when keys are renamed, removed or change type. `failed --json` (or `failed list --json`) only lists; it cannot be combined with `retry` or `clear`. Command results and JSON go to stdout; errors and warnings go to stderr. Exit codes are listed in [the Guide](docs/Guide.md#exit-codes). When stdout is not a terminal (a pipe, a file, cron), or with `memanga --plain`, output is plain text: no colour, emoji, borders or line wrapping, and `check` prints one summary line. `NO_COLOR` turns colour off. Diagnostics on stderr show warnings and errors by default; `memanga -v` adds progress, `-vv` debug details, and `memanga -q` hides warnings so only errors show (`check --quiet` only stops prompts). `MEMANGA_LOG_LEVEL` (`DEBUG`, `INFO`, `WARNING`, `ERROR`) sets the level when no flag is given. `memanga --log-file` also writes `diagnostics.log` in the config folder. These options go before the command: ```bash MEMANGA_LOG_LEVEL=INFO python -m memanga check --download python -m memanga -vv --log-file check "Blue Lock" --dry-run ``` ```bash python -m memanga failed --json | jq -r '.chapters[] | "\(.title) #\(.chapter)"' python -m memanga doctor --json --check browsers --launch-browsers ``` #### Python API `memanga.api` is the supported way to read a library from Python. It only reads: opening a `Library` never writes `config.yaml` or `state.json`, never repairs a damaged state file, never creates or moves the config folder (a library still in the old `~/.config/memanga` is read there) and works while a check or the desktop app is running. Checks, downloads and edits stay with the commands above; run them with `subprocess` and read their exit codes and `--json` output. Every other `memanga` module is internal and may change in any release. ```python from memanga.api import Library, LibraryError library = Library() # or Library("/path/to/config"); $MEMANGA_CONFIG_DIR works too for series in library.series(status="reading"): print(series.position, series.title, series.last_chapter, len(series.downloaded_chapters), series.failed_chapters) ``` Each `Series` has `position` (the `#N` the commands accept), `title`, `status`, `mode`, `sources` (each with `name` and `url`, primary first), `last_chapter`, `downloaded_chapters`, `failed_chapters` and `send_to_kindle`. `library.get(title)` returns one manga by its exact title or `None`, `library.download_dir` is where chapters are saved, and `library.reload()` reads the files again. Results are snapshots and can't be changed. A config folder that doesn't exist, or a config or state file that can't be loaded or holds a value of the wrong type, raises `LibraryError`. ### Shell completion `memanga completion bash` prints a bash completion script for commands, options, their choices and the source names for `search --source`. Load it from `~/.bashrc`: ```bash source <(memanga completion bash) ``` Only bash is supported for now; zsh and fish have no script yet. The script completes the `memanga` command; regenerate it after upgrading so new commands, options and sources show up. Tracked manga titles are not completed: the script is static and never reads your library or config, so nothing runs on TAB. Use `#N` from `memanga list` to name a manga quickly, e.g. `memanga rm '#3'`. --- ## Sources The default search selection includes these 15 sources, in search order. Their availability can change; check the Sources page for current health. | Source | Notes | |---|---| | mangadex.org | Fan-translation library | | mangapill.com | General library | | mangapark1.com | General library | | mangafire.to | General library | | mangabuddy.com | General library | | weebcentral.com | General library | | mangakatana.com | General library | | asurascans.com | Manhwa specialist | | comix.to | General library | | comick.io | General library | | mangahub.io | MangaHub network | | mangahere.cc | General library | | mangapanda.onl | MangaHub network | | mangahere.onl | Alternate mirror | | mangataro.org | ComicK replacement | For every registered domain, see the [supported sources](docs/SUPPORTED_SOURCES.md). --- ## Build from source ```bash git clone https://github.com/meellm/MeManga.git cd MeManga python scripts/bootstrap.py # one-time venv setup # Dev build — console window stays open for tracebacks python build.py # → ./MeManga-Dev.exe (or ./MeManga-Dev) # Release build — no console, identical pins as the GitHub release python build_app.py # → release/MeManga/ (release/MeManga on macOS) ``` Both scripts sweep their `build/` + `dist/` scratch dirs after. The dev build is a single file at the repo root. The release build is a folder with the `MeManga` launcher and its `_internal/` files on Windows and Linux (so the bundled LGPL libraries stay replaceable) and a single file on macOS, which the release workflow wraps in `MeManga.app`. Both install `requirements/build.txt` (exact pins with hashes for every transitive dep, generated from `pyproject.toml`). See [CONTRIBUTING.md](CONTRIBUTING.md) for project layout, test commands, scraper-add walkthroughs, and the lock-refresh flow. --- ## Where your data lives MeManga keeps its files in the config folder of your platform: | Platform | Config folder | |---|---| | Windows | `%APPDATA%\memanga\` (usually `C:\Users\\AppData\Roaming\memanga\`) | | macOS | `~/Library/Application Support/memanga/` | | Linux and others | `$XDG_CONFIG_HOME/memanga/`, or `~/.config/memanga/` when `XDG_CONFIG_HOME` is not set | | Path | What | |---|---| | `/config.yaml` | Library, settings, source toggles, theme | | `/state.json` | Read/unread state, download history, source health | | `/*.bak` | Previous copy of `config.yaml` / `state.json`, kept on every save | | `/state.json.corrupt-*` | A damaged state file, kept for recovery instead of being overwritten | | `/covers/` | Cover image cache | | `/crash.log` | Uncaught exceptions from the windowed release exe | | `/runtime.log` | Diagnostics from the windowed release exe; the last three sessions are kept as `runtime.log.1` to `.3` | | `/memanga.log` | Output of the daily check set up with `cron install` on Linux and macOS | | `/diagnostics.log` | Timestamped diagnostics written with `memanga --log-file` (rotated at 1 MB, three old files kept) | | `~/Downloads/MeManga//` | Default download folder (changeable in Settings) | `memanga config path` prints the config file in use. Earlier versions used `~/.config/memanga/` on every platform. When that folder holds a library and the platform folder does not, the first start of the app or any command moves it there (a single rename, nothing is copied or deleted) and leaves a `MOVED.txt` note in the old folder, so scheduled checks installed earlier keep running. If the platform folder already holds a library, it is used and the old folder is left alone. MeManga keeps using the old folder, unchanged, when another MeManga is running, when the platform folder exists and is not empty, when your settings point to a path inside the old folder (for example a download folder), or when the move fails, for example because the folders are on different drives. MeManga can use another directory for `config.yaml` and `state.json`: `memanga --config-dir DIR <command>` (the option goes before the command, also `memanga --config-dir DIR --gui`), or set `MEMANGA_CONFIG_DIR=DIR`. The CLI and the desktop app choose the same way: 1. `--config-dir DIR` (CLI and `memanga --gui`) 2. `MEMANGA_CONFIG_DIR` (CLI, `memanga --gui` and the desktop app started on its own) 3. the platform folder above A chosen directory is used as is and never moves the old folder. The app's settings, library, lock, logs (`runtime.log`, `crash.log`) and cover cache all live in it. `cron install` and the daily check set up in the app's Settings keep a chosen directory in the scheduled check. Sensitive credentials (SMTP App Password) are stored in the OS keyring (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux). Without a usable keyring the password is saved in plain text in `config.yaml`, and MeManga says so with the file's path; keep that file private. On servers and in containers, the app password can come from the environment instead and is then never saved: - `MEMANGA_SMTP_PASSWORD_FILE` names a file holding the password (for example a Docker secret under `/run/secrets/`); a trailing newline is ignored. - `MEMANGA_SMTP_PASSWORD` holds the password itself. Environment variables can be seen by other tools on the same machine, so prefer the file. Either one is used instead of the keyring and `config.yaml`. Setting both, or naming a file that cannot be read, leaves MeManga without an app password, and `memanga doctor` reports why. --- ## FAQ **Will my downloads work without internet?** Yes. Once a chapter is on disk it opens in the reader without a connection. The app disables network actions (Search, Check, Download) when it detects you're offline and enables them again when the connection returns. **Does it send analytics?** No. No telemetry, no accounts, and crash reports are never sent automatically. Crash details go to `crash.log` locally; you can attach that file to a bug report. The desktop app contacts: - **The manga sources you use** and the image servers their pages and covers come from. - **A connection check:** every 30 seconds (every 5 while offline) it opens a connection, with no data sent, to the first reachable of `1.1.1.1:53`, `cloudflare.com:443` and `github.com:443`, so it can tell when you are offline. Turn it off in **Settings → Advanced → Network & Privacy** (offline detection is then off too), or list your own hosts in `config.yaml`: ```yaml gui: network_check_hosts: - "192.0.2.1:80" ``` Only valid `host:port` entries are used. A list with none sends no check at all (it never falls back to the hosts above). Settings lists any ignored entries, and `memanga config edit` rejects them. - **MangaDex, for covers:** when a manga has no cover or its cover no longer loads, the app searches MangaDex by title. This never happens while MangaDex is turned off in **Sources**, and you can turn it off in **Settings → Advanced → Network & Privacy**. - **The sources in your search results, for chapter counts:** each result's chapter list, which can take several requests. Turn it off in **Settings → Advanced → Network & Privacy** ([Search](#search) has the details). - **Your mail server**, only if you set up Kindle / email delivery. - **Playwright's download server**, once, for the browser driver on first launch. The same switches exist as `gui.network_check`, `gui.mangadex_cover_fallback` and `gui.search_chapter_counts` for `memanga config set`. **Why does the first launch take a while?** It downloads Playwright's Firefox build (about 80 MB), which sources that need a browser use. This happens once, behind a progress dialog. **A source I use stopped working — what now?** - Check **Sources → Re-check health** for status. If it's red, the site may be down or may have changed its pages. File an issue with the **Scraper broken** template. - Use the [search-result chapter chip](#search) to spot sources that return nothing: they show no `N ch` chip. - Switch your manga to a backup source (Detail page → Edit) until the scraper is fixed. **Can I use this on headless devices?** Yes. The CLI runs anywhere Python 3.11+ runs, and its browsers start headless, so no display is needed. Use `memanga cron install` or `memanga watch` for scheduled checks (see [Schedule daily checks](#schedule-daily-checks) and [Docker](#docker)). --- ## Contributing Pull requests are welcome, including bug fixes, new scrapers and interface improvements. See [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, test commands, and PR checklist. There are issue templates for [bugs](.github/ISSUE_TEMPLATE/bug_report.md), [features](.github/ISSUE_TEMPLATE/feature_request.md), and [broken scrapers](.github/ISSUE_TEMPLATE/scraper_broken.md). For security-sensitive reports, see [SECURITY.md](SECURITY.md). ## License MIT — see [LICENSE](LICENSE). The release downloads and the Docker image include third-party software under its own licenses. Their notices ship with every release asset (`THIRD_PARTY_NOTICES.txt`) and in the Docker image under `/usr/share/doc/memanga/`, for example: ```bash docker run --rm --entrypoint cat meellm/memanga:latest /usr/share/doc/memanga/THIRD_PARTY_NOTICES.txt ```