A manga and web novel aggregator that works everywhere, desktop, mobile, and browser. Run it locally with no server, or self-host for syncing across devices.
- Read anything. Manga in a paged reader, novels with adjustable typography, RTL support, and per-work style overrides. Download chapters for offline reading.
- Scrape anything. WASM or Lua plugins from community repositories — zero sources bundled, install from settings.
- Track everything. Sync reading progress to AniList, MyAnimeList, or Kitsu.
- Translate novels. Local inference via Ollama, or bring your own API key. Community glossary refines translations over time.
- Migrate sources. Moving from a dead scraper? Match works by title and carry read state to a new source.
Download from Releases — Linux, macOS, Windows, Android, iOS.
In local mode (default), the app runs entirely on your device. SQLite on disk, no login, no server process, no network calls unless you import a work. Install plugins, build your library, read offline, it all works without an internet connection.
Remote mode connects to a hosted Manga Vault server for syncing your library and progress across devices. Link your devices through Settings, and the sync happens in the background.
Local archive reading supports CBZ files and image folders, add a folder path in Settings → Local, and browse your existing collection.
- Paged mode for manga (single page per screen), continuous scroll for novels
- Per-work overrides: font size, line spacing, image margins, image gap, each work remembers its own settings
- RTL support for right-to-left manga
- Resume: the reader remembers your scroll position per chapter
- Keyboard nav: arrow keys switch chapters, Escape returns to work page
- Notifications: opt-in alerts when library works get new chapters (configurable in Settings)
If you want your library and progress available on multiple devices, run the server and switch to remote mode on each client.
cd deploy
cp .env.example .env # fill in SECRET_KEY, POSTGRES_PASSWORD
docker compose up -dRequires: Docker, PostgreSQL. The web frontend is a separate static deployment (Cloudflare Pages or any static host).
cargo build --release
./target/release/manga-vault # SQLite by default
DATABASE_URL=postgres://... ./target/release/manga-vaultThe web frontend is a separate static site, pointed at the server via PUBLIC_API_URL:
cd clients/web
pnpm install && pnpm build:cloudflare # Cloudflare Pages (recommended)
# or
pnpm install && pnpm build:static # any static host (nginx, Caddy, etc.)If you have data in the old manga-vault (MySQL), there's a one-shot migration binary in tools/migrate. It reads from your legacy MySQL database and writes into a new SQLite or Postgres target.
# Build the tool
cargo build -p manga-vault-migrate --release
# Run the migration
./target/release/manga-vault-migrate \
--from mysql://user:password@localhost:3306/old_vault \
--to sqlite://./manga-vault.dbWhat it migrates:
- Works — manga and novels into a unified table, deduplicated by remote URL
- Chapters — image and novel chapters sorted by original date, duplicate URLs collapsed
- Library entries — favorites with category assignments carried over
- Reading progress — which chapters each user has read, duplicates collapsed
- Users and categories — carried over with new UUIDs
After migration, the tool prints a verification table comparing row counts between the legacy and new databases. If counts don't match, the legacy database should be kept as a cold backup and investigated before retiring it.
# Example output:
# entity legacy new
# works 432 432 ok
# chapters 12847 12847 ok
# library_entries 312 312 ok
# reading_progress 8102 8102 ok
# users 3 3 okThe legacy source must be MySQL (the old manga-vault supported MySQL). The target can be either SQLite or Postgres, use Postgres if you plan to run the new server in hosted mode.
Manga Vault ships no scrapers. Add a repository URL in Settings → Sources:
https://github.com/Dewn5228/manga-vault-plugins/releases/download/latest/repo.json
The community repository is auto-published by GitHub Actions on every push. Plugins are self-contained WASM components or Lua scripts, no inter-plugin dependencies, sandboxed at runtime.
Implement the Source trait via WIT (WASM) or Lua. Host standard library available to all plugins:
http.get(url) html.find(doc, selector)
flare_solverr.get(url) html.attr(elem, name)
No shared utils at runtime, shared code stays in the author's build tooling.
# Server
git clone https://github.com/Dewn5228/manga-vault.git && cd manga-vault
cargo build --release
# Web UI
cd clients/web && pnpm install && pnpm build:static
# Desktop / mobile
cd clients/flutter && flutter build linux # or macos, windows, apk, ios
# WASM plugins
rustup target add wasm32-wasip2
cargo component build --target wasm32-wasip2 --release- CI (
ci.yml): Rust clippy + tests, web typecheck + lint, Flutter analyze - Desktop (
desktop.yml): Linux/macOS/Windows builds on tag push → release archives - Mobile (
mobile.yml): Android APK + unsigned iOS on tag push - Plugins (
plugin-repo/.github/workflows/publish.yml): WASM builds →.mvplugartifacts → GitHub Release +repo.jsoncommit
| Variable | Default | Purpose |
|---|---|---|
DATABASE_URL |
sqlite://manga-vault.db |
SQLite or Postgres connection |
BIND_ADDR |
127.0.0.1:18080 |
API listen address |
SECRET_KEY |
— | Encrypts tracker/translation credentials |
ADMIN_USERNAME |
— | Grants plugin management access |
OLLAMA_ENDPOINT |
— | Instance-wide translation via Ollama |
TRANSLATION_ENABLED |
true |
Kill switch for translation |
PLUGINS_DIR |
./plugins |
Plugin storage path |
IMAGE_CACHE_MB |
512 |
Proxy cache size for images |
FLARESOLVERR_URL |
— | Byparr / FlareSolverr for Cloudflare sources |
CORS_ORIGINS |
— | Allowed cross-origin origins |
PUBLIC_API_URL |
`` | API URL for the web UI |