myspoti
Native Android client for Spotify, built with Jetpack Compose
A self-hosted manga and comic book reader. Like Jellyfin, but for CBZ files.
MediaTypeScript · RustGitHub @73gonOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Manga reader panel
Translation pending
Loading the full README.
Read the full README ↗A self-hosted manga and comic book reader -- like Jellyfin, but for CBZ files.
OpenPanel scans your comic/manga library (CBZ, CBR and CB7) and your light novels (EPUB), indexes pages from ZIP archives without extracting them, generates thumbnails, and serves a responsive web reader with continuous-scroll and single-page modes, RTL/LTR support, reading progress tracking, bookmarks, collections, and multi-user support.
JoJo's Bizarre Adventure/Part 1 …/, Part 2 …/) becomes a story group: one poster in the library that opens to its parts in order, or every part on its own, as each reader likes; a series shows which part it is, and the end of a part leads on to the nextOrganize your files like this:
/path/to/manga/
+-- One Piece/
| +-- Chapter 001.cbz
| +-- Chapter 002.cbz
| +-- ...
+-- Naruto/
| +-- Vol 01.cbz
| +-- ...
+-- Standalone Book.cbz
Each subfolder becomes a series. Books directly in the root become standalone books. CBZ, CBR and CB7 files are read as pages, EPUB files as text. PDF files are listed by name only, without their pages.
Clone the repository:
git clone https://github.com/youruser/openpanel.git
cd openpanel
Install frontend dependencies:
cd ui
npm install
Start the backend:
cd server
cargo run
The server starts on http://localhost:3001.
Start the frontend dev server:
cd ui
npm run dev
The dev server starts on http://localhost:3000 and proxies /api calls to :3001.
Open the app: Go to http://localhost:3000
First-time setup:
The backend is configured through environment variables (or a .env file in the server/ directory):
| Variable | Default | Description |
|---|---|---|
OPENPANEL_PORT | 3001 | Server port |
OPENPANEL_BIND | 0.0.0.0 | Address to listen on; 127.0.0.1 keeps the server to this machine (behind a reverse proxy) |
OPENPANEL_DATA_DIR | ./data | Where the SQLite database and thumbnails are stored |
DATABASE_URL | sqlite://<DATA_DIR>/openpanel.db | SQLite database URL |
OPENPANEL_LIBRARY_ROOTS | (empty) | Comma-separated folders added as libraries on startup, named after the folder (optional, libraries can also be added via admin UI) |
OPENPANEL_DEV_MODE | false | Enables CORS for localhost:5173 |
OPENPANEL_LOG_LEVEL | info | Tracing log level (debug, info, warn, error) |
OPENPANEL_ZIP_CACHE_SIZE | 200 | Number of ZIP indexes to keep in the LRU cache |
OPENPANEL_UNPACK_CACHE_MB | 4096 | Room for RAR and 7z books unpacked for reading (in <DATA_DIR>/unpacked); least recently read go first |
OPENPANEL_PUBLIC_URL | http://localhost:3001 | Public URL (used for CORS in production) |
OPENPANEL_SCAN_ON_STARTUP | true | Scan libraries when the server starts; false overrides the setting in Administration |
Example .env:
OPENPANEL_PORT=3001
OPENPANEL_DATA_DIR=./data
OPENPANEL_DEV_MODE=true
OPENPANEL_LIBRARY_ROOTS=/home/user/manga,/home/user/comics
OPENPANEL_LOG_LEVEL=info
Edit docker-compose.yml -- update the volume mounts to point to your library folders:
volumes:
- openpanel-data:/data
- /your/manga/folder:/libraries/manga:ro
- /your/comics/folder:/libraries/comics:ro
Start the stack:
docker compose up -d
Access the app: http://your-server:3001
Add libraries via Admin:
/libraries/manga)Caddyfile -- replace openpanel.example.com with your domaindocker-compose.yml, uncomment the caddy servicedocker compose up -d
docker build -t openpanel .
docker run -d \
-p 3001:3001 \
-v openpanel-data:/data \
-v /path/to/manga:/libraries/manga:ro \
--name openpanel \
openpanel
Build the frontend:
cd ui
npm ci
npm run build
This outputs static files to ui/dist/.
Build the backend:
cd server
cargo build --release
Run:
cd server
OPENPANEL_DATA_DIR=/var/lib/openpanel OPENPANEL_PORT=3001 ./target/release/openpanel-server
The server serves the frontend from ui/dist/ automatically.
+-------------+ +--------------+ +--------------+
| React SPA |------>| Axum (Rust) |------>| SQLite DB |
| (Vite PWA) | API | REST API | | (WAL mode) |
+-------------+ +------+-------+ +--------------+
|
+-------v-------+
| CBZ Files |
| (ZIP on disk)|
+---------------+
@zonsh/ui, on Base UI) — see Design system.The interface is built with @zonsh/ui: its components, its material (layered primary, raised secondary, recessed fields, hairline structure), the Licht typefaces and lucide icons. Follow its brand guide (zon.sh/ui/brand.md) when changing the UI: monochrome surfaces with colour only for meaning, Licht for headings, Licht Sans for reading, Licht Mono for labels and numbers.
@zonsh/ui). To move to a newer zon/ui, run npm install @zonsh/ui@latest in ui/ and check its changelog for breaking changes./licht/fonts/*.woff2, and the server fetches them from www.zon.sh (in development, Vite's zonFonts() proxy does the same). The server therefore needs outbound HTTPS to www.zon.sh; without it the UI falls back to system fonts./api to http://localhost:3001; set OPENPANEL_API_TARGET to use another server.All API routes are under /api/. Auth routes are public; most others require a Bearer token.
Full documentation: docs/API.md · OpenAPI spec: docs/openapi.yaml (also served at /api/openapi.yaml)
| Method | Path | Description |
|---|---|---|
| GET | /api/health | Health check |
| POST | /api/auth/register | Register a new user |
| POST | /api/auth/login | Login (returns token) |
| POST | /api/auth/logout | Logout (invalidates token) |
| GET | /api/auth/me | Current user info |
| GET | /api/auth/status | Setup status (needs first user?) |
| GET | /api/libraries | List all libraries |
| GET | /api/libraries/:id/series | List series in a library (paginated) |
| GET | /api/series | List all series (sort, genre, status) |
| GET | /api/series/:id/books | List books in a series |
| GET | /api/series/:id/chapters | List detected chapters in a series |
| GET | /api/series/:id/metadata | Get/set/clear AniList metadata |
| GET | /api/genres | List all available genres |
| GET | /api/books/:id | Book details |
| GET | /api/books/:id/pages/:num | Stream a page image |
| GET | /api/books/:id/thumbnail | Book thumbnail (WebP) |
| GET | /api/series/:id/thumbnail | Series thumbnail (WebP) |
| GET/PUT | /api/progress | Get/update reading progress |
| GET | /api/progress/batch | Batch get progress for multiple books |
| GET | /api/continue-reading | Continue reading list (server-side) |
| GET/POST | /api/bookmarks | List/create bookmarks |
OpenPanel is a full PWA — you can install it as an app on any device:
MIT
| DELETE | /api/bookmarks/:id | Delete a bookmark |
| GET/POST | /api/collections | List/create collections |
| GET/DEL | /api/collections/:id | Get/delete a collection |
| POST | /api/collections/:id/items | Add series to collection |
| DELETE | /api/collections/:id/items/:series_id | Remove series from collection |
| GET/PUT | /api/preferences | Get/update user preferences |
| GET | /api/version | Server version info |
| GET/PUT | /api/admin/settings | App settings (admin only) |
| POST | /api/admin/scan | Trigger library scan |
| GET | /api/admin/scan/status | Scan progress |
| POST | /api/admin/libraries | Add a library |
| PUT/DEL | /api/admin/libraries/:id | Update/remove a library |
| GET | /api/admin/libraries/browse | Browse server directories |
| GET/POST | /api/admin/profiles | List/create users |
| DELETE | /api/admin/profiles/:id | Delete a user |
| PUT | /api/admin/password | Change password |
| POST | /api/admin/update | Trigger server update |
| GET | /api/admin/check-update | Check for updates |
| GET | /api/admin/logs | View admin logs |
| POST | /api/admin/backup | Create database backup |
| GET | /api/admin/backups | List backups |