About Codexa

A self-hosted EPUB and comic book reader with KOReader sync, OPDS browsing, and offline support

Codexa is a self-hosted reading platform for your EPUB books and comic books — your own private library that follows you across every device. It runs as a single lightweight Node.js container, needs no cloud account, and keeps everything — books, covers, highlights, bookmarks, and reading positions — on your own server. Open it in any modern browser, install it as a Progressive Web App, or use the dedicated Android and iOS apps. Pick up exactly where you left off, on any of them.

What sets Codexa apart is CXReader, its own purpose-built rendering engine. Instead of leaning on a generic third-party EPUB library, Codexa renders books with code written specifically for reliability, faithful typography, and — crucially — flawless behaviour on slow e-ink screens. The result is a reader that handles stubborn real-world EPUBs, fixed-layout manga, and CBZ/CBR comics with the same care, and stays fast on a BOOX or Kobo.

It began as a personal itch. I was running Grimmory/Booklore as my ebook server, with a fleet of devices syncing through its OPDS catalog and KOReader sync server. Later I migrated to more resource friendly Book Orbit server, but some of my EPUBs rendered poorly in the web reader, and two-way Grimmory ↔ KOReader sync wasn't working for me. Unable to find a web-based reader that did everything I needed, I built my own. It grew far beyond a weekend project — so I'm sharing it in case it's useful to you too.

Everything stays local, with optional two-way synchronisation to KOReader devices over the open KOSync protocol — Codexa even includes its own KOSync-compatible server, so your e-reader and your phone stay on the same page without any extra software.

Codexa library view showing book covers in a grid
The Codexa library — all your books in one place

At a Glance

  • Single Node.js process — easy to deploy with Docker in minutes
  • Multi-user with JWT authentication — per-user libraries
  • Full offline reading — via a Service Worker cache
  • CXReader — Codexa's own custom-built EPUB engine for reliable rendering
  • Comic book support — read CBZ and CBR files alongside your EPUB library
  • Built-in KOSync-compatible server — connect KOReader devices without extra software
  • OPDS catalog browser — for Calibre-Web, Book Orbit, Booklore Komga, Kavita, and others; downloads books directly
  • Works on any device — desktop browsers, mobile PWA, Android APK, iOS IPA
  • Optimised for e-ink displays — BOOX, Kobo, and similar
↑ Top

Features

Everything included in Codexa

📖 Reading

  • CXReader — Codexa's own EPUB engine; reflowable, fixed-layout, and comic book formats
  • CBZ & CBR comic books — two-page spread on desktop, ComicInfo.xml metadata, theme-aware background
  • Fixed-layout EPUB — manga, children's books, and art books at pixel-accurate dimensions
  • Paginated layout — with configurable margins and columns
  • Exact position restore — reopens at the precise page, not just an approximate percentage
  • Bookmarks — with custom labels
  • Highlights — in four colours (yellow, green, blue, pink) with notes
  • In-book full-text search — with result navigation
  • StarDict dictionary lookup — double-click on desktop, long-press on mobile
  • CJK-aware word selection — proper Chinese/Japanese/Korean word segmentation, including single-character lookups; native OS selection handles on mobile
  • Footnote and endnote popups — without leaving the page
  • Bionic reading — bolds word prefixes to guide the eye
  • Two-page spread — for wider screens
  • Page-turn animations — none, fade, slide, paper, momentum, or zoom, with optional finger-tracking drag
  • Sleep timer — dim, close the book, or release keep-screen-on after a set time
  • Fullscreen mode
  • Auto-hiding toolbar

🌟 Display & Themes

  • 7 built-in themes — Light, Sepia, Dark, Sepia Dark, Midnight, Nord, plus Custom with free color picking
  • E-ink mode — high-contrast black-and-white for e-ink displays
  • Custom fonts (TTF/OTF/WOFF/WOFF2) uploaded by admin
  • Extensive text settings — font, size, line height, letter spacing, indentation, hyphenation
  • Configurable status bar — with up to 6 overlay slots
  • Screen edge padding — for curved screens and notches
  • Presets — save theme/font/layout settings as a named preset, switchable from the Theme tab; presets sync across devices, each device remembers its own current preset

🔁 Sync & Progress

  • Automatic position saving — on every device
  • Built-in KOSync-compatible server — for KOReader devices
  • External KOSync server support — with conflict resolution
  • BookOrbit extended sync — optional two-way sync of highlights, reading sessions, live reading progress, and book status/rating to a self-hosted BookOrbit server
  • BookOrbit Dash — account-wide reading stats panel: streak, editable yearly goal, currently-reading shelf, library overview, and a daily highlight
  • Interrupted session recovery banner
  • Reading statistics — time read, pages turned, sessions, books started/finished

📱 Offline & Mobile

  • Download any book for offline reading — via Service Worker cache
  • PWA — installable on desktop and mobile
  • Android app — with volume-key navigation, portrait lock, hardware e-ink toggle
  • iOS app — IPA file sideload (work in progress)
  • Responsive layout — for phones, tablets, and desktops

📚 Library

  • Multi-user with JWT authentication — per-user libraries
  • Shelves — organise books into named collections
  • Online library — browse OPDS catalogs from Calibre-Web, Book Orbit, Booklore, Komga, Kavita, and more, with a folder tree, card grid, grid density control, and per-server reachability status; download books or peek them read-only without downloading first
  • Bulk shelf sync — from OPDS folder with stale-book detection
  • OPDS-linked shelves — synced shelves remember their source folder; one click opens it in the OPDS browser or re-triggers a sync
  • Native BookOrbit library browser — browse libraries, smart scopes, collections, series, and authors on a self-hosted BookOrbit server; add books to Codexa or peek them without downloading
  • BookOrbit collection sync — link a Codexa shelf to a BookOrbit collection or smart scope, same one-click resync as OPDS-linked shelves
  • Related books — "Similar books," "More by author," and "More in series" recommendations from a connected BookOrbit server, in both the local book info modal and the BookOrbit library's own book detail modal
  • Series support — with series name, number, and one-click filter
  • Sort — by date, title, author, progress, or series
  • Real-time library search

🛡 Admin

  • User management — view all accounts, delete users
  • Font management — upload (with progress indicator) and delete custom fonts for all users
  • Dictionary management — upload StarDict ZIP archives (with progress indicator)
  • Registration control — enable or disable new-user sign-up
  • Refresh book metadata — re-extract genres, descriptions, and covers from all EPUB files
Reader view
Reader
E-ink mode
E-ink Mode
Dictionary lookup popup
Dictionary
Online library OPDS browser
Online library OPDS browser
Library view
Library view
Dark mode
Dark mode
↑ Top

Installation

Deploy with Docker or build from source

Docker (Recommended)

The quickest way to run Codexa is with Docker Compose.

1. Create your compose file

cp docker-compose.sample.yaml docker-compose.yaml

Or create docker-compose.yaml with this content:

services:
  codexa:
    image: codeberg.org/thj/codexa:latest
    container_name: codexa
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - codexa_data:/data
    environment:
      JWT_SECRET: "replace_with_a_long_random_secret_string_at_least_64_chars"
      # CORS_ORIGIN: "https://books.example.com"
      # PORT: "3000"
volumes:
  codexa_data:

2. Generate a JWT secret

JWT_SECRET is required and must be at least 64 characters. The server will refuse to start without it. Generate one with either command:

node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
openssl rand -hex 64

Paste the output into docker-compose.yaml as the value of JWT_SECRET.

⚠ Keep your JWT secret safe Changing JWT_SECRET will invalidate all active sessions — every user will be logged out. Store it in a password manager or secrets vault.

3. Start the container

docker compose up -d

Codexa is now running at http://localhost:3000. Register the first account — it will automatically become the admin.

Environment Variables

VariableRequiredDefaultDescription
JWT_SECRET Yes Long random string (≥ 64 chars). Signs session tokens. Changing it logs everyone out.
PORT No 3000 TCP port the server listens on.
DATA_DIR No ./data Path to persistent storage (books, covers, fonts, dictionaries, database).
CORS_ORIGIN No same-origin Allowed CORS origin, e.g. https://books.example.com. Only needed when the app is served from a different origin than the API.
DEBUG No false Set to true to enable verbose browser console logging. When enabled, all internal messages ([reader], [api], [kosync], [CXReader], etc.) appear in DevTools. Off by default — only warnings and errors are shown.
OIDC_PROVIDERS and OIDC_<KEY>_* No (none) Enable OIDC login (Google, Apple, self-hosted) as an alternative to local registration. See OIDC / Single Sign-On for the full variable reference and setup examples.

Updating

docker compose pull
docker compose up -d

The data volume is preserved across updates. The database schema is migrated automatically on startup.

Manual Build from Source

Requires Node.js ≥ 18.

git clone https://codeberg.org/thj/codexa.git
cd codexa
cp .env.example .env
# Edit .env and set JWT_SECRET
npm install
npm run build
npm start
CommandDescription
npm run buildBundles and minifies the client-side assets. Run this after every pull.
npm startStarts the server. Reads configuration from environment variables or .env.
npm run devStarts with nodemon — auto-restarts on file changes (development only).

Behind a Reverse Proxy

Codexa serves plain HTTP. Put it behind nginx, Caddy, or Traefik to add HTTPS. Set client_max_body_size to at least 300 MB so large EPUB uploads are not rejected.

Nginx:

server {
    listen 443 ssl;
    server_name books.example.com;

    location / {
        proxy_pass         http://127.0.0.1:3000;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        client_max_body_size 300M;
    }
}

Caddy:

books.example.com {
    # Set the max body size to 300MB
    request_body {
        max_size 300mb
    }

    # Proxy all traffic to your app
    reverse_proxy 127.0.0.1:3000
}
↑ Top

Mobile Apps

Install Codexa on any phone or tablet

Progressive Web App (PWA)

The easiest way to use Codexa on mobile. No app store needed — install directly from the browser.

  • Android (Chrome): tap the install icon in the address bar, or open the browser menu and choose "Add to Home screen".
  • iOS (Safari): tap the Share button △ → "Add to Home Screen".
  • Desktop (Chrome/Edge): click the install icon in the address bar.

Once installed, Codexa opens in fullscreen without browser chrome, just like a native app.

Mobile library view
Mobile library
Mobile reader
Mobile reader

Android APK

The Android APK is a native wrapper that integrates Codexa with hardware features not available in a browser.

Installation

  1. Download the APK from the Codeberg Releases page.
  2. On your Android device, go to Settings → Security (or Apps → Special app access) and enable Install from unknown sources for your browser or file manager.
  3. Open the downloaded APK and tap Install.
  4. Launch Codexa. On first run you will see a URL input screen — enter your Codexa server address (e.g. https://books.example.com).

Changing the Server URL

From the reader, press the hardware back button twice quickly to return to the server selection screen. You can then enter a new URL.

E-ink Mode

The URL input screen has an E-ink mode toggle. When enabled, Codexa applies a grayscale colour filter system-wide, increases contrast, and disables animations. This setting is saved across restarts.

Hardware Features

  • Volume keys: navigate pages with the physical volume up/down buttons (enable in reader Settings → Device).
  • Portrait lock: prevent screen rotation (Settings → Device).
  • Screen on: keep the display awake while reading (Settings → Device).
  • Fullscreen: automatically hides Android navigation and status bars while in the reader.
Compatibility The Android app is compatible with older WebView versions and handles known quirks in Chrome 83-era WebView found on some e-ink devices.
E-ink mode on Android
E-ink mode
Dictionary on mobile
Dictionary on mobile

iOS App

The iOS app is built with Capacitor and wraps the Codexa web app in a native container. Distribution is available via two paths:

Path A — Free Sideload (no Apple account fee)

  1. Download the .ipa file from the Forgejo Actions artifacts (available 30 days after each build).
  2. Install Sideloadly on Windows or macOS. iTunes drivers are required on Windows.
  3. Connect your iPhone/iPad via USB, open Sideloadly, drag in the IPA, and click Start.
  4. On the device: go to Settings → General → VPN & Device Management and trust the developer certificate.
⚠ 7-day expiry Sideloaded apps signed with a free Apple ID expire after 7 days. Re-sign with Sideloadly or use AltStore for automatic renewal over Wi-Fi.

Path B — TestFlight / App Store ($99/year)

With an Apple Developer Program membership you can build and distribute via TestFlight or publish to the App Store. The repository includes a Fastlane configuration for automated builds. See the iOS/ folder for setup instructions.

First Launch

A "Connecting…" splash screen appears briefly. Tap it to enter your Codexa server URL. The app keeps the screen on while reading and hides the iOS status bar for fullscreen content.

↑ Top

Data Directory

Where Codexa stores everything

All persistent data lives in a single directory — ./data by default, or the path set by the DATA_DIR environment variable. Mount this directory as a Docker volume to preserve data across container updates.

data/
├── codexa.db         # SQLite database (WAL mode)
├── books/
│   └── {user_id}/
│       ├── {sha256}.epub
│       └── {sha256}.cbz   # CBR files converted to CBZ
├── covers/
│   └── {sha256}.jpg
├── fonts/
│   └── {fontname}.ttf / .otf / .woff / .woff2
└── dictionaries/
     ├── en-sl/oxford/   # StarDict files inside
     └── merriam-webster/

Details

codexa.db

SQLite database running in WAL (Write-Ahead Logging) mode. Stores users, books metadata, reading progress, annotations, bookmarks, settings, and shelf assignments. The schema is migrated automatically on startup — you never need to run manual migrations.

books/

Book files (EPUB and CBZ) are stored per-user in subdirectories named by the numeric user ID. Each file is named by its SHA-256 hash, so duplicate uploads are rejected (same content = same hash). The original filename is stored in the database. CBR files are converted to CBZ before storage — only .epub and .cbz files appear on disk.

covers/

Cover images extracted from EPUB metadata during upload. Shared across all users (same book hash → same cover). Served directly by the web server with HTTP caching.

fonts/

Custom fonts uploaded by admins. Available to all users in the reader's Text settings. Supported formats: .ttf, .otf, .woff, .woff2.

dictionaries/

StarDict dictionary files. Each dictionary lives in its own subdirectory. The naming convention lang-from-lang-to/dict-name/ (e.g. en-sl/oxford/) is used to infer source and target languages, but any directory structure is valid. Dictionaries are shared across all users.

Backup tip To back up everything, copy the entire data/ directory. The SQLite database can be backed up live with sqlite3 codexa.db ".backup backup.db".
↑ Top

First Login

Register the first account and get started

When you open Codexa for the first time, you will see the login page. No default admin password exists — you must register an account.

Register
Register a new user

Registering

  1. Navigate to your Codexa server URL in a browser.
  2. Click Register on the login page.
  3. Enter a username (3–32 characters, letters, numbers, and underscores only), an optional email address, and a password (minimum 8 characters).
  4. Click Register. You will be logged in automatically.

The email address is optional and can also be added later from Settings → General → Email. Setting it lets you sign in with either your username or your email, and lets a matching OIDC login link to this account automatically instead of creating a separate one.

⭐ First user is the admin The very first account registered on a fresh Codexa instance is automatically the administrator. The admin account has access to user management, font uploads, dictionary uploads, and the registration toggle. There is no separate admin setup step.

Logging In

Enter your username or email address, and your password, on the login page. Sessions last 1 year. If your session expires, you will be redirected to the login page.

Login
Login

Security

  • Passwords are hashed with bcrypt before storage — they are never stored in plain text.
  • Login attempts are rate-limited to 10 per 15 minutes per IP address.
  • Sessions use JWT tokens signed with your JWT_SECRET.

Changing Your Password

Go to Settings → General → Change password. Enter your new password twice (minimum 8 characters) and click Save.

Setting or Changing Your Email

Go to Settings → General → Email, enter an address, and click Save email. This is entirely optional, but has two effects once set:

  • You can log in with either your username or your email address.
  • A matching, verified email from an OIDC provider (Google, Apple, self-hosted) will link to this account automatically on first sign-in, instead of creating a new one — see OIDC / Single Sign-On.

Each email address can only be used by one account. Clearing the field (saving it empty) removes it — you can then only log in with your username again, and it will no longer match any OIDC identity.

Disabling Registration

After creating all the accounts you need, an admin can disable new-user registration to prevent unauthorised sign-ups. See Settings → Admin.

OIDC / Single Sign-On

As an alternative to local username/password registration, Codexa can log people in via any standard OIDC provider — Google, Apple, or a self-hosted identity provider you run yourself. It's disabled by default; setting OIDC_PROVIDERS turns it on, and one "Sign in with…" button appears on the login page per configured provider.

How Account Matching Works

A successful OIDC login is matched against existing Codexa accounts in two steps:

  1. By provider + subject ID — if this exact identity has logged in before, it reuses that account.
  2. By verified email — otherwise, if the provider vouches for the email (sends email_verified: true) and it matches the email set on an existing, not-yet-linked local account (Settings → Email, or set at registration), that account is linked instead of creating a new one. This is what lets someone who already registered locally start using OIDC without ending up with a second, empty account — the email just needs to match on both sides.

If neither matches and new registrations are currently allowed (see Settings → Admin → Registration), a new account is auto-created. If registration is disabled, an unrecognised identity is rejected instead of silently creating an account — you'll see a message on the login page explaining that an admin needs to either re-enable registration or link an existing account's email.

🔒 Email linking is verified-only An email match only ever links to an account that isn't already linked to a different identity, and only when the provider explicitly marks the email as verified. A provider that doesn't assert email_verified (or sends no email at all) always falls through to creating a new account rather than linking by an unverified email — otherwise a misconfigured or malicious provider could take over an unrelated account just by claiming its email address.
⚠️ Not included: Facebook Facebook doesn't implement standard OIDC (no discovery document, no id_token), so it can't use this generic integration. Google, Apple, and any self-hosted provider (Dex, Authelia, Keycloak, Authentik, …) are all real OIDC and work out of the box.
ℹ️ OIDC accounts and KOReader Sync An account created via OIDC has no local password, so it can't be used to log in to KOReader Sync (which authenticates with username/password). Go to Settings → General → Change password first if you need that account to also work with KOReader Sync.

Example: Google

  1. Create an OAuth 2.0 Client ID in the Google Cloud Console (Web application), with an authorized redirect URI of https://<your-domain>/api/auth/oidc/google/callback.
  2. Set the environment variables:
OIDC_PROVIDERS=google
OIDC_BASE_URL=https://<your-domain>
OIDC_GOOGLE_ISSUER=https://accounts.google.com
OIDC_GOOGLE_CLIENT_ID=<your client id>
OIDC_GOOGLE_CLIENT_SECRET=<your client secret>
OIDC_GOOGLE_NAME=Google

Apple (Sign in with Apple) works the same way with OIDC_APPLE_ISSUER=https://appleid.apple.com, except Apple's "client secret" is itself a JWT you generate and sign with an Apple private key, valid for at most 6 months — you'll need to regenerate and redeploy it periodically.

Example: Self-Hosted Provider with Predefined Users (Dex)

If you'd rather not open the door to a third-party account at all, you can run your own minimal OIDC provider with a fixed list of users you define yourself. Dex is a good fit for this — a single small container, no database, users declared directly in its config file.

dex-config.yaml:

issuer: https://auth.example.com/dex
storage:
  type: memory
web:
  http: 0.0.0.0:5556
staticClients:
  - id: codexa
    name: Codexa
    secret: <a-random-client-secret>
    redirectURIs:
      - https://books.example.com/api/auth/oidc/dex/callback
enablePasswordDB: true
staticPasswords:
  - email: "alice@domain.com"
    # Generate with: htpasswd -bnBC 10 "" '<password>' | tr -d ':\n'
    hash: "<bcrypt hash>"
    username: "alice"
    userID: "1"
  - email: "bob@doma.com"
    hash: "<bcrypt hash>"
    username: "bob"
    userID: "2"

Add Dex as a second service in your docker-compose.yaml:

services:
  codexa:
    image: ghcr.io/thehijacker/codexa:latest
    # ...existing config...
    environment:
      JWT_SECRET: "..."
      OIDC_PROVIDERS: "dex"
      OIDC_BASE_URL: "https://books.example.com"
      OIDC_DEX_ISSUER: "https://auth.example.com/dex"
      OIDC_DEX_CLIENT_ID: "codexa"
      OIDC_DEX_CLIENT_SECRET: "<the same random client secret as above>"
      OIDC_DEX_NAME: "Home SSO"

  dex:
    image: dexidp/dex:latest
    container_name: dex
    restart: unless-stopped
    ports:
      - "5556:5556"
    volumes:
      - ./dex-config.yaml:/etc/dex/config.yaml
    command: ["dex", "serve", "/etc/dex/config.yaml"]

Put both books.example.com and auth.example.com behind your reverse proxy (see Reverse Proxy) with HTTPS — OIDC providers generally require HTTPS redirect URIs. Only the usernames/passwords you add to staticPasswords will ever be able to log in to Codexa this way.

Linking an Existing Local Account

Already have a local account and want to switch it over to OIDC without losing your books and progress? Go to Settings → Email and set the same email address that's configured for you on the OIDC provider (e.g. the same value as Dex's staticPasswords[].email), then sign in with that provider. Since the email matches an existing, unlinked account, Codexa links to it instead of creating a new one.

💡 Already created a duplicate account by accident? If you signed in via OIDC before setting a matching email and ended up with a second, empty account: set the matching email on your original account (Settings → Email), delete the duplicate account (Settings → Admin → User Management), then sign in via OIDC again — this time it will link to the original account.

OIDC Environment Variables

VariableRequiredDescription
OIDC_PROVIDERS No Comma-separated list of provider keys to enable, e.g. google,dex. Leave unset to disable OIDC entirely — no buttons appear and nothing else in this section applies.
OIDC_BASE_URL Only if OIDC_PROVIDERS is set Public base URL Codexa is reachable at, used to build each provider's callback URL.
OIDC_<KEY>_ISSUER Only for each key in OIDC_PROVIDERS The provider's OIDC issuer URL (its discovery document lives at <issuer>/.well-known/openid-configuration).
OIDC_<KEY>_CLIENT_ID / _CLIENT_SECRET Only for each key in OIDC_PROVIDERS Credentials for the OAuth client you registered with that provider.
OIDC_<KEY>_NAME No Display label for the provider's button on the login page. Defaults to the key itself.
↑ Top

Settings

Configure KOReader sync, BookOrbit sync, OPDS servers, dictionaries, and admin options

Open Settings by by choosing gear icon Settings option from the left menu sidebar.

General settings
General settings
KOReader Sync settings
KOReader Sync settings
Bookorbit settings
Bookorbit settings
OPDS servers settings
OPDS servers settings
Dictionaries settings
Dictionaries settings
Admin settings
Admin settings
Admin settings
Admin settings
Admin settings
Admin settings

General

  • Auto-open last book: when enabled, Codexa automatically opens the most recently accessed book when you visit the library. Stored in your browser's local storage.
  • Email: optional. Lets you log in with your email as well as your username, and lets a matching verified OIDC login link to this account automatically. See Setting Your Email.
  • Change password: enter a new password (minimum 8 characters) and confirm it, then click Save.

KOReader Sync

Codexa can synchronise your reading position with KOReader devices in two ways: using its built-in sync server, or connecting to an external KOSync server.

Built-in KOSync Server

Codexa includes a KOSync-compatible server at /kosync. Enable it with the Internal KOSync server toggle. The settings page will show you the URL to enter in your KOReader device.

In KOReader:

  1. Go to Tools → KOReader Sync
  2. Set Custom sync server to your Codexa URL (e.g. https://books.example.com)
  3. Log in with the same username and password you use in Codexa

Reading positions are synced automatically when you open or close a book. The server stores a high-water mark — it only advances your position, never goes backwards.

External KOSync Server

You can also connect to a separate KOSync-compatible server (e.g. a shared community server). Enter the server URL, username, and password, then tap Test connection. If the test passes, click Save.

The Clear button removes all stored external server credentials.

BookOrbit

BookOrbit has its own settings tab, separate from KOReader Sync. It has two independent purposes: browsing your BookOrbit library from inside Codexa, and optionally syncing highlights, reading sessions, live reading progress, and book status/rating with that same server. See BookOrbit Library and BookOrbit Sync for a full description of each.

  1. Enter your BookOrbit server URL. This is its own field — it no longer needs to match the URL saved under KOReader Sync → External KOSync Server, though it usually points at the same server.
  2. Click Test connection to confirm Codexa can reach the server.
  3. To also enable extended sync, enter your BookOrbit account username and account password (your BookOrbit web login — this may differ from the KOReader sync sub-account credentials), tick Enable BookOrbit extended sync, then click Save.

Only the server URL is required to browse the BookOrbit library. The extended-sync toggle stays disabled (greyed out) until a server URL and account password are both saved. Saving the credentials and the toggle in a single click is supported — you do not need to save them separately first.

⚠ Unreachable server If the saved BookOrbit URL cannot be reached, a warning badge appears next to the BookOrbit entry in the sidebar and in the reader. Progress sync with KOReader/KOSync is unaffected — only BookOrbit browsing and extended sync depend on this connection.

OPDS Servers

Add catalog servers that appear in the Online library.

  • Click Add OPDS server to expand the form.
  • Enter a server name, the catalog URL, and optional username and password for protected catalogs.
  • Click Add server to save.
  • Each saved server has Open (go to Online library), Edit, and Delete buttons.

Dictionaries

Every user can configure their own dictionary preferences independently — changes here are personal and do not affect other users. The dictionary files themselves are global (installed by an admin and available to everyone), but the order and language labels are stored per account.

  • Language labels: set From and To language codes (ISO 639-1, e.g. en, de) for each installed dictionary.
  • Order: click the up/down arrows to change which dictionary's results appear first during lookup.

Changes take effect immediately in the reader.

Admin

The Admin section is visible only to the administrator. Admins are identified as the user with the lowest ID (the first account ever registered on this server).

Registration

Toggle Allow new registrations to enable or disable the registration link on the login page. Disable this after setting up all accounts to prevent unauthorised sign-ups. This also governs OIDC login: with registration disabled, an OIDC identity that doesn't already match an existing account (by prior login or verified email) is rejected instead of auto-creating a new one.

User Management

Lists all registered users. Click the delete (×) button next to a user to permanently remove their account and all associated books, annotations, and settings.

Font Management

Upload custom fonts that will be available to all users in the reader's Text settings. Supported formats: .ttf, .otf, .woff, .woff2. Up to 50 files per upload; maximum 50 MB per file.

The reader automatically groups font files into families based on their filename. If you name files using the convention FontName-Weight.ext, all variants appear as a single entry in the font picker and bold/italic are applied automatically:

  • MyFont-Regular.ttf
  • MyFont-Bold.ttf
  • MyFont-Italic.ttf
  • MyFont-BoldItalic.ttf

Recognised weight keywords: Thin, ExtraLight, Light, Regular, SemiBold, Bold, ExtraBold, Black. Recognised style keywords: Italic, Oblique. Files sharing the same stem before these keywords are grouped into one family ("MyFont" in the example above).

Dictionary Management

Upload a .zip archive containing a StarDict dictionary. The ZIP must contain the .ifo, .idx, and .dict (or .dict.dz) files. Up to 10 ZIPs per upload; maximum 200 MB per ZIP.

The ZIP filename (without .zip) becomes a subfolder inside data/dictionaries/, and the archive contents are extracted into it. For example, uploading en-sl-oxford.zip creates data/dictionaries/en-sl-oxford/. The folder name is also used as the dictionary's ID, so naming ZIPs with a language prefix (e.g. en-de-langenscheidt.zip) lets Codexa infer source and target languages automatically.

Uploaded dictionaries are immediately available to all users. Click the delete button next to a dictionary to remove it from the server.

Refresh Book Metadata

The ↺ Refresh metadata for all books button re-reads genres, description, cover image, publisher, language, ISBN, and page count directly from every EPUB file on disk and updates the database. Title and author are not overwritten so any manual edits are preserved.

Use this after updating books on an OPDS server and re-downloading them, or if books were added to the library before a newer version of Codexa that extracts additional fields (such as genre tags). The same action is also available in the library's Edit mode (select the "All Books" tab, enable Edit, then click ↺ Refresh metadata in the toolbar).

↑ Top

Dictionary Lookup

Look up words instantly using StarDict dictionaries

Dictionary lookup popup showing word definition
Dictionary popup in the reader

How It Works

Dictionary lookup can be triggered in different ways depending on your device:

  • Desktop browser — double-click: double-clicking a word opens the dictionary immediately without any extra steps.
  • Desktop browser — drag selection: drag the cursor over a word or phrase to select it. A bottom toolbar appears; click the dictionary icon to look up the selection.
  • Mobile / touch: long-press a word to start a selection, using your device's own native selection handles to extend or shrink it if needed, just like selecting text anywhere else. The bottom toolbar appears while anything is selected; tap the dictionary icon on it to look up the selection. Selecting text on its own never triggers a lookup — only the dictionary icon does. Tapping outside the selection clears it and closes the toolbar.
Bottom toolbar with dictionary icon
Bottom toolbar — appears on selection (desktop) or long-press (mobile)

A bottom sheet slides up showing all definitions found across your enabled dictionaries. If multiple dictionaries are enabled, each result is labelled with its dictionary name. If no exact match is found, Codexa shows words with similar spelling as suggestions.

Chinese, Japanese & Korean Text

Codexa uses real word segmentation for Han/Hiragana/Katakana text (via the browser's Intl.Segmenter) instead of treating an entire punctuation-delimited clause as one "word." Double-clicking or long-pressing selects the actual word or character under your cursor/finger, and single-character words (a lone Han character, for example) are looked up correctly instead of being silently skipped.

On mobile, text selection — Latin or CJK — uses your device's own native selection with draggable handles, the same as selecting text in any other app, so you can extend or shrink a selection freely instead of being limited to whatever Codexa guessed. The one exception is iOS, where the browser doesn't expose native selection handles to web pages; there, long-press selects the tapped word/character directly, and long-pressing elsewhere picks a different one instead of dragging to extend.

Installing Dictionaries

Codexa uses the StarDict format. A dictionary consists of at least three files:

  • .ifo — dictionary metadata (name, word count)
  • .idx — word index
  • .dict or .dict.dz — compressed definitions

Option 1 — Upload a ZIP (admin)

  1. Create a ZIP archive containing the StarDict files for one dictionary.
  2. Go to Settings → Admin → Dictionaries.
  3. Click Upload dictionary ZIP and select your file.
  4. The dictionary is extracted and becomes immediately available to all users.

Option 2 — Place files directly

Copy StarDict files into the data/dictionaries/ folder on the server. Arrange them in subdirectories — one subdirectory per dictionary. The naming convention lang-from-lang-to/dict-name/ (e.g. en-sl/oxford/) is optional but allows Codexa to infer the dictionary's language.

No server restart is required — dictionaries are discovered at lookup time.

Enabling and Reordering

  • In the reader sidebar → Dictionaries tab: toggle checkboxes to enable/disable dictionaries for the current session. Use the up/down arrows to change priority.
  • In Settings → Dictionaries: set language labels (From/To) and change the default order. Preferences are saved to your account.

Dictionaries higher in the list appear first in the lookup popup.

Dictionary settings
Enable and reorder dictionaries
↑ Top

Online Library

Browse and import books from any OPDS-compatible catalog

Online library OPDS browser showing catalog entries
Online library OPDS browser with catalog navigation

Getting Started

OPDS (Open Publication Distribution System) is a standard catalog format supported by Calibre-Web, BookOrbit, Booklore, Komga, Kavita, Ubooquity, Bookwyrm, and many other self-hosted book servers. There are also a number of public OPDS catalogs available online. To browse an OPDS catalog, you must first add it as a server in Codexa.

  1. Go to Settings → OPDS Servers and add at least one server (name, URL, and optional credentials).
  2. Open the Online library from the sidebar — it only appears once at least one server is configured.
  3. The first server is selected automatically; its root folder loads right away.
Server status Every configured server is checked for reachability as soon as the panel opens, and shown with a colored dot in the server list — green for reachable, red for unreachable — so you don't have to click through each one to find out.

Browsing

The layout mirrors the BookOrbit library browser, adapted for OPDS's one real difference: catalogs nest into arbitrarily deep folders, where BookOrbit's own sections are flat.

  • Left sidebar — the server list, and below it a folder tree for whichever server is selected. Clicking a folder expands its subfolders directly underneath it, indented one step further right, so the tree always shows exactly the path you're on — no separate expand/collapse state to lose track of.
  • Breadcrumb & Up button — shown above the catalog on the right. Both stay in sync with the folder tree: clicking a breadcrumb segment or the Up button moves the tree's highlighted row back up to match.
  • Right pane — subfolders are shown as clickable tiles; books in the current folder are shown below them as a grid of cover cards. A folder containing only books shows just the card grid, with no tile section at all.
  • Grid density — the same compact/normal/large control used by the main library and BookOrbit, in the top-right of the toolbar. It's a single shared preference: changing it here changes it everywhere.
  • If the server supports OpenSearch, a search box appears at the top of the catalog pane.
  • On narrow screens, the sidebar collapses into an off-canvas drawer opened with the ☰ button.

Downloading a Single Book

Each book card shows different actions depending on whether it's already in your library:

StateActions shown
Not yet downloaded + (download into your library) and ℹ Info
Already downloaded Read, Peek (bottom-right of the cover), and ℹ Info

Clicking + downloads the book immediately — metadata (title, author, cover, series) is extracted automatically, and the card switches to the downloaded state in place. ℹ Info opens a full details dialog once the book is downloaded; beforehand it opens a lighter preview (cover, title, author, and description) sourced directly from the catalog entry, since that's all an OPDS server ever exposes for a book you haven't downloaded yet.

Peek Without Downloading

The Peek button works even before you download a book — tap it on any card and Codexa fetches the file into a temporary location, opens it read-only, and cleans it up automatically as soon as you close the reader (closing sends you right back to the same server and folder you were browsing). If the reader is closed abruptly instead of normally — a crash or a force-quit — a background sweep on the server removes the temporary file within a few hours regardless, so nothing is ever left behind.

If the book turns out to already be in your library, Peek (and Info) opens it directly instead of fetching a second temporary copy.

Folder Sync to Shelf

Click the sync icon next to any folder — on a tile in the right pane, or on its row in the left folder tree — to bulk-import the entire folder into a Codexa shelf, keeping it in sync with the source catalog.

  • A pre-flight count is shown before you confirm — so you know how many books will be downloaded.
  • Progress is streamed in real time. Books already in your library are skipped (no duplicate downloads).
  • Books that were previously synced but are no longer in the catalog are flagged as stale.
  • Re-running a sync on the same shelf adds new books and reports removals without deleting anything automatically.
  • Tick Force redownload all books before confirming to re-download every book in the folder regardless of whether it already exists in the library. Each file is replaced on disk, its MD5 is recomputed, and all metadata fields (genres, description, cover, language, etc.) are refreshed from the new file. Title and author are not overwritten. Use this after updating book files or metadata on the OPDS server.
Supported catalog types Codexa handles both OPDS 1.x (Atom XML) and OPDS 2.x (JSON) catalogs, and resolves relative URLs and authentication automatically.

Linked Shelves

When you run Sync to Shelf for the first time, Codexa records the OPDS server and folder URL on that shelf — making it a linked shelf. Linked shelves appear with a distinct icon in the sidebar so you can tell them apart from manually-created shelves at a glance.

Whenever you open a linked shelf in the library, a banner appears at the top showing the last sync date and time alongside two quick-action buttons:

  • Open in OPDS — switches to the Online Library panel and navigates directly to the source folder. You can browse new arrivals or individually pick books to download without running a full sync.
  • Sync again — opens the sync dialog pre-filled with the source folder and always targets the same shelf, even if the shelf has been renamed since the original sync.

Automatic Background Sync

Opening a linked shelf also triggers a silent background sync. Codexa checks the source OPDS folder for new books and downloads any it finds — no dialog, no spinner, no interruption to your browsing. A one-hour cooldown per shelf prevents repeated checks when you switch shelves quickly.

  • If new books are found while you are viewing the shelf, the library refreshes automatically.
  • If new books are found while you are on a different shelf, a badge appears on the linked shelf's sidebar entry showing the count. The badge clears when you open that shelf.
  • Stale-book warnings (books removed from the catalog) are never shown during auto-sync — they appear only on a manual Sync again.

Removing the Link

To detach a shelf from its OPDS source, hover over the shelf in the sidebar, click the edit (✎) icon, and press Unlink from OPDS. The shelf and all its books are kept; only the OPDS connection is removed. The shelf reverts to a regular manually-managed shelf.

While a shelf is linked, a book's checkbox for it is locked in the book details Shelves tab — unlink the shelf first if you need to remove a book from it by hand.

Shelf identity is preserved Re-syncing a linked shelf always updates the same shelf by ID, not by name. You can freely rename the shelf in the sidebar without breaking the OPDS link.
↑ Top

Themes

Light, dark, sepia, and e-ink display modes

Reader Themes

Codexa includes seven reading themes. Select one in Reader → Settings → Theme.

ThemeDescription
LightWhite background, dark text — classic day reading.
SepiaWarm cream background, dark text — easy on the eyes in bright rooms.
DarkDark grey background, light text — comfortable in dim light.
Sepia DarkWarm dark background, light text — combines warmth with low brightness.
MidnightPure black background, light text — maximum battery saving on OLED.
NordCool blue-grey palette inspired by the Nord colour scheme.
CustomPick your own background and text colour using colour pickers that appear when this theme is selected.

Override Book Styles

Enable Override book styles in the Theme tab to force the reader's fonts and colours on books that define their own CSS. Useful for books with hard-coded dark text that doesn't adapt to dark themes.

E-ink Mode

E-ink mode switches the entire interface to high-contrast black and white, disables colour transitions and shadows, and reduces animations. It is designed for e-ink display devices such as BOOX readers.

E-ink mode on a BOOX device
E-ink mode — desktop view
E-ink mode on mobile
E-ink mode — mobile

Enabling E-ink Mode

  • In the reader: Settings → Theme tab → enable E-ink mode.
  • Android app: toggle on the server URL input screen. The setting is persisted across restarts — no need to re-enable after closing the app.
  • From the library: tap the theme icon in the library header and select E-ink. This switches the library to black and white and also forces the reader into e-ink mode whenever a book is opened.

App Theme (Library)

The library interface follows the system's light/dark preference automatically. An Appearance selector at the bottom of the library sidebar lets you lock it to Light, Dark, System, or E-ink independently of the system setting. When E-ink mode is selected here, the reader automatically opens in e-ink mode as well — no need to configure it separately inside the reader.

Display Size

On large, high-resolution screens — 7–10″ e-ink readers (BOOX, ...), tablets, and even big desktop monitors — a standard interface can feel cramped. The Display size selector at the bottom of the library sidebar scales the whole library up so it's comfortable to read and tap, with an even, predictable progression. Larger sizes also flow into the touch-friendly layout (collapsible hamburger menu, full-width book grid) where there's room.

OptionEffect
AutoDefault. Uses the device's native size — no scaling.
LargeEnlarges the interface about 1.25×.
LargerEnlarges the interface about 1.5×.
LargestEnlarges the interface about 1.75× — the biggest comfortable step.

The setting applies instantly (no reload), is remembered per device, and is independent of the theme. It affects the library; the reader has its own size controls (font size, status-bar text, and header-button size in Reader → Settings).

Works everywhere Display size now works on desktop browsers too, not just phones, tablets, and the Android app — Codexa automatically picks the right scaling technique for each platform, so the control behaves the same wherever you read.

Presets

Save your current theme, font, and layout settings as a named preset, and switch between them instantly from Reader → Settings → Theme. Handy for keeping, say, a high-contrast setup for an e-ink device and a softer sepia setup for a phone, without reconfiguring every setting each time you switch between them.

ActionEffect
Save as presetCreates a new preset from your current settings.
UpdateOverwrites the selected preset with your current settings.
RenameRenames the selected preset.
DeleteRemoves the selected preset.

A preset captures every setting across the Theme, Text, Page, Device, and Status Bar tabs — except dictionary selection, which is never part of a preset and keeps its own behaviour (matching a book's language automatically, or whatever you've set manually).

Synced, but not shared, across devices Your presets — their names and settings — are available on every device you log in to. Which preset is currently applied, however, is remembered separately per device, so an e-ink reader and a phone can each stay on their own preset instead of one device's choice overwriting every other device's.

Selecting a preset updates your current settings immediately; it does not touch any per-book overrides already saved for the book you have open — use Reset for this book at the top of the Settings panel if you want a preset to fully take over a book with its own overrides.

↑ Top

Supported Languages

The Codexa interface is available in 8 languages

LanguageCodeStatus
EnglishenDefault
GermandeAvailable
FrenchfrAvailable
ItalianitAvailable
SpanishesAvailable
PortugueseptAvailable
SlovenianslAvailable
Simplified Chinesezh-CNAvailable

How Language is Selected

Codexa detects the preferred language from your browser's Accept-Language header and loads the appropriate locale file automatically. If your browser language is not supported, English is used as the fallback.

Hyphenation Languages

The reader supports automatic word hyphenation for the following languages (configured in Settings → Text → Word hyphenation):

Slovenian, English, German, French, Italian, Spanish, Portuguese, Dutch, Polish, Czech, Croatian, Slovak, Russian, Ukrainian

Hyphenation dictionaries are selected per-book. If a book's language metadata matches one of the supported languages, it is pre-selected automatically.

↑ Top

Uploading Books

Add EPUB, CBZ, and CBR files to your library

Accepted Formats

FormatExtensionDescription
EPUB.epubStandard e-book format — reflowable or fixed-layout
CBZ.cbzComic Book ZIP — a ZIP archive of ordered image files
CBR.cbrComic Book RAR — automatically converted to CBZ on the server

Maximum file size is 300 MB per upload.

Upload Methods

File Picker

  1. Open the library.
  2. Click the Upload button (⇧ icon) in the toolbar.
  3. Select one or more .epub, .cbz, or .cbr files from your device.
  4. The files are uploaded, metadata is extracted, and covers are generated automatically.

Drag and Drop

Drag one or more files from your file manager and drop them anywhere on the library page. A drop overlay appears to confirm the action.

From Online Library

Navigate to a book or comic in the Online Library and click Add to library. EPUB, CBZ, and CBR files are all supported. CBR files are detected by their file signature and converted to CBZ automatically.

OPDS Folder Sync

Use Sync to Shelf in the OPDS browser to bulk-import an entire catalog folder. See Online library for details.

Duplicate Detection

Codexa computes a SHA-256 hash of each uploaded file. If the same content already exists in your library, the upload is rejected with a friendly message — no duplicates are stored. CBR files are converted to CBZ before hashing, so re-uploading the same comic as either format is correctly detected as a duplicate.

Metadata Extraction

EPUB

The following metadata is extracted automatically from the EPUB OPF file:

  • Title, author
  • Cover image
  • Series name and number (Calibre tags or EPUB3 belongs-to-collection)
  • Description, publisher, language, ISBN
  • Genre tags, page count

CBZ / CBR

If the archive contains a ComicInfo.xml file (the standard comic metadata format), Codexa extracts:

  • Title, series name and number
  • Writer and penciller (combined into the author field)
  • Summary (description) and genre
  • Cover image (first image in the archive, sorted by filename)
  • Page count

If ComicInfo.xml is absent, the filename is used as the title and the first image becomes the cover.

If a book is missing genres or other fields (for example because it was uploaded before a newer version of Codexa), use Settings → Admin → ↺ Refresh metadata for all books to re-extract everything from the files on disk.

↑ Top

Library

Browse, search, and organise your book collection

Library grid view with book covers
Library grid
Library search results
Real-time search

Browsing

Books are shown as a grid of covers. Below each cover the title, author, series (if any), and a reading progress bar are displayed.

Desktop (mouse): hover over a cover to reveal the action buttons. Click the cover or any empty area on the card to open the reader directly.
Touch: a single tap reveals the action buttons. A second tap on the card opens the reader.

The action buttons that appear on each card are:

  • 👁 Cover preview — shows the full-size cover image in a popup (only shown when the book has a cover).
  • ℹ Info — opens the book details dialog with metadata, shelves, KOSync status, and quick actions.
  • Download / Delete offline — caches the EPUB locally for offline reading, or removes it from the local cache if already downloaded. A ✓ badge on the cover indicates a book is cached.
  • Read — opens the book in the reader immediately, resuming from the last position.

A Peek button is also permanently visible in the bottom-right corner of every cover (shown on hover on desktop, always visible on touch). Peek opens the book without saving your reading position — useful for a quick preview.

A ⋮ quick menu is available at the bottom-right corner of every book card. Click or tap it to open a compact popup with the same four actions — Read, Peek, Info, and Download/Remove offline — without needing to hover over the cover first. This is particularly useful on touch devices where the hover actions are not always easy to reach.

Keyboard Navigation

The book grid is fully keyboard-navigable. Focus a cover (Tab into the grid or click a card), then move around with the arrow keys.

KeyAction
/ Focus the previous / next book in the row
/ Focus the book above / below
EnterOpen the focused book — or toggle its selection while in Edit mode

The search bar at the top of the library filters books in real time by title, author, and genre. Results update as you type — no need to press Enter.

Sort Order

Click the sort menu (☰) in the library toolbar to change the sort order:

  • Recently Added — newest uploads first (default)
  • Last Opened — most recently read books first
  • Title — alphabetical by book title
  • Author — alphabetical by author name
  • Progress — sort by reading percentage
  • Series — group by series name and number

Density Toggle

Click the density button (▦) to cycle through three cover sizes: compact (more books per row), normal, and large. Your preference is saved.

Library Shelf Tabs

The sidebar shows three built-in views at the top of the Shelves section:

  • All Books — every book in your library.
  • Currently Reading — books you have opened at least once, not yet at 100%.
  • Downloaded — books cached for offline reading.

Read Status & Rating

Each book can carry a read status and a star rating (1–5). Open the book info dialog (ℹ button) to set them:

  • Status — Want to Read, Reading, Read, or Abandoned.
  • Rating — click a star to set 1–5; click the same star again to clear it.

Once set, a coloured status pill and star icons appear below the title on the book card so you can see your status and rating at a glance without opening the info dialog. When BookOrbit Sync is enabled, status and rating are kept in sync with your BookOrbit library automatically.

Edit Mode

Click the Edit button to enter edit mode. In edit mode you can:

  • Select multiple books by tapping their covers.
  • Assign selected books to one or more shelves.
  • Delete selected books (with confirmation).

Click Done to exit edit mode.

Reading Statistics

Codexa tracks your reading activity per book and in aggregate. Statistics include time read, pages turned, reading sessions, books started, and books finished. Access per-book statistics from the Book Details dialog → Reading tab.

↑ Top

Shelves

Organise your books into named collections

Shelves are custom collections that appear in the left sidebar. Use them to group books by genre, reading list, project, or any organisation that suits you.

Creating a Shelf

  1. In the sidebar, find the Shelves heading.
  2. Click the + icon next to it.
  3. Enter a name for the shelf and press Enter or click Save.

Adding Books to a Shelf

  • From edit mode: click Edit in the library toolbar, select the books you want to add, then click Add to Shelf and choose the target shelf.
  • From book details: open the Book Details dialog → Shelves tab → toggle the shelf checkboxes.

Editing and Deleting Shelves

Hover over a shelf name in the sidebar to reveal the edit (✎) and delete (×) buttons. Deleting a shelf removes the shelf but does not delete the books in it.

Reordering Shelves

Click the edit shelves (✎) button next to the Shelves heading to enter reorder mode. Each shelf gains a drag handle (⟿) — drag a shelf up or down to change its position in the sidebar. The new order is saved and kept across devices. Click the edit button again to leave reorder mode.

OPDS Folder Sync

Navigate to any folder in the Online Library and click the Sync to Shelf button. The folder's books are downloaded and added to a named shelf. Re-running the sync:

  • Downloads new books that appeared in the catalog since the last sync.
  • Skips books already in your library (duplicate detection by file hash).
  • Reports books that were removed from the catalog (stale books) — you decide whether to keep or remove them.

Linked Shelves

After a sync, the shelf becomes linked to the OPDS source folder. Linked shelves have a distinct icon in the sidebar and show a banner across the top of the library displaying the last sync time and two buttons:

  • Open in OPDS — jumps straight to the source folder in the Online Library without any manual navigation.
  • Sync again — reopens the sync dialog targeting this shelf. Even if you rename the shelf, the link is preserved — the sync always updates the correct shelf.

Opening a linked shelf also triggers a silent background sync. New books are downloaded automatically without any dialog. If new books arrive while you are browsing a different shelf, a badge on the sidebar entry shows the count of new books waiting. The background sync runs at most once per hour per shelf.

To remove the OPDS link, click the edit (✎) icon on the shelf and press Unlink from OPDS. The shelf and its books are kept; it simply becomes a regular shelf.

Manually-created shelves are never linked. Only shelves created (or updated) by an OPDS sync have the linked icon and banner.

A shelf can be linked the same way to a BookOrbit collection or smart scope instead of an OPDS folder — see Sync to a Shelf in the BookOrbit Library section. The banner, resync button, and unlink option all work identically.

↑ Top

Offline Reading

Read your books without an internet connection

Offline reading indicator
Offline indicator in the reader

How It Works

Codexa uses a Service Worker to cache files in your browser. There are three stores working together:

  • App shell cache — the HTML, CSS, JavaScript, and fonts that make up the Codexa interface. This is cached automatically on your first visit, so the app loads without a network connection even if you haven't downloaded any books.
  • Book cache — the book files (EPUB and comic CBZ/CBR) you download for offline use, together with their cover images. Each book is stored individually and can be removed without affecting other cached books.
  • On-device database (IndexedDB) — book metadata (title, author, cover, reading percentage) plus your bookmarks and highlights. This lets the library and reader show the right information while you're offline.

A book counts as available offline only when its file is genuinely in the book cache — the Downloaded shelf reflects what is actually on the device, so you never see a book you can't open.

Downloading a Book for Offline Use

  1. Tap a book cover in the library to open its details.
  2. Click Download for offline reading.
  3. Progress is shown in the dialog. When complete, the book is available offline.

You don't always have to do this manually: while you're online, Codexa quietly downloads the books you're currently reading in the background, so they're ready if you lose connectivity. Both the file and its cover are cached.

Reading Offline

When your device has no network connection, the library automatically switches to showing only downloaded books. All reader features work normally offline:

  • Your reading position is saved on the device as you turn pages and when you close the book.
  • Bookmarks and highlights are stored in IndexedDB (the on-device database).
  • Dictionary lookups work for dictionaries that are served from your server (available offline only if the server is reachable or the dictionary is cached).

What Happens When You Come Back Online

The moment Codexa detects the connection is back — including waking a phone or e-reader that was asleep the whole time you were offline — it silently reconciles your position with KOReader sync (KOSync). There's no prompt and nothing to confirm:

  • You read further than the last known synced position — your progress is pushed automatically. Any position you read offline is held in a small on-device queue until it can be sent, so nothing is lost even if the reconnect happens after you've closed the book or moved on to another one.
  • Another device already read further — Codexa pulls that position and jumps you forward to it automatically, no dialog. This only ever moves you forward; it will never silently roll your position back.
  • Both sides already match — nothing happens.
  • The queue is reliable: if you reconnect while reading a different book, positions from earlier offline sessions still sync, and anything that can't be sent yet is retried on the next reconnect or app launch.

This automatic reconcile is separate from the manual sync tap zones and the confirmation dialog you see when opening a book that moved on another device — see KOReader Sync for those.

At the same time, OPDS catalog data refreshes and any new books added on the server appear in the library.

Removing a Downloaded Book

Open the book's details dialog and click Remove from device. The EPUB is removed from the local cache but remains in your server library.

You can also view all downloaded books in the Downloaded shelf in the library sidebar.

↑ Top

Book Details

View metadata, manage shelves, and access sync options

Book details dialog with tabs
Book details dialog

Open the book details dialog by tapping the ℹ Info button on a book card. It has four tabs and five quick-action buttons at the top.

Quick Actions

ButtonAction
ReadOpen the book in the reader, restoring your last position.
PeekOpen in read-only mode — your reading position is not saved. Useful for previewing a book without advancing your progress.
DownloadDownload the EPUB file to your device (Save As dialog).
OfflineCache the book for offline reading (or remove from cache).
DeletePermanently delete the book from your library (with confirmation).

Details Tab

Shows the book's full metadata:

  • Cover image
  • Title, author
  • Series name and number
  • Tags / genres
  • Publisher, publication language, ISBN
  • File size, date added to library
  • Current reading progress (percentage and last position)
  • Description (from EPUB metadata)

Shelves Tab

A list of all your shelves with checkboxes. Toggle a shelf to add or remove this book from it, then click Save shelves.

Shelves linked to an OPDS folder or a BookOrbit collection/smart scope show a 🔒 lock icon and their checkbox is disabled — membership in a linked shelf is driven entirely by the linked source, not by hand. To move a book out of a linked shelf, either change its membership at the source (see the Collections Tab below, for BookOrbit) or unlink the shelf entirely from its edit dialog.

Book details dialog with shelves tab
Book details shelves dialog

Collections Tab

Shown for any book already matched to a BookOrbit entry, regardless of whether it's in a linked shelf. A checklist of every BookOrbit collection you have — tick or untick collections and click Save collections to update membership directly on the BookOrbit server, the same editor available from a book card in the BookOrbit browser, without needing to leave this dialog.

If you untick a collection that's linked to one of this book's shelves, Codexa notices immediately and asks whether to just unassign the book from that shelf or remove it from your library outright — the same choice shown when a linked sync finds a book no longer in its source collection. Choosing to keep it leaves the book in your library, unassigned from that shelf, still visible under All Books.

Book details dialog with collections tab
Book details collections dialog

KOSync Tab

Shows the reading progress last received from your KOReader device:

  • Current position (CFI) and percentage
  • Device name and sync timestamp

KOSync hash override: KOReader identifies books by an MD5 hash of the file. If your Codexa EPUB and KOReader's copy are slightly different (e.g. different editions), the hashes won't match. Enter the MD5 hash from KOReader here to link them manually.

Re-download from OPDS: if this book was originally imported from an OPDS source, you can force-download the latest version from that source URL.

Search to replace: search a source and swap in a different file for this book — for example a better-quality copy or a different edition. If BookOrbit is set up, it appears first in the source dropdown above your OPDS servers. Metadata shown elsewhere in the dialog refreshes immediately after a replacement, no need to close and reopen it.

If this book is linked to a BookOrbit id, a View on BookOrbit link opens it on your BookOrbit server in a new tab.

Book details dialog with KOSync tab
Book details KOSync dialog

Reading Tab

  • Last read position and percentage
  • Total reading time and number of sessions
  • Annotation (highlight + note) count
  • Bookmark count
Book details dialog with Reading tab
Book details Reading dialog

Shown when BookOrbit Sync is enabled and the book is linked to a BookOrbit id. Powered by BookOrbit's recommendation engine, with up to three sections: More in series, Also by this author, and More like this. Each result links out to the book's page on BookOrbit. The same recommendation data — plus a "Next in series" pick when you've finished the book — backs the Related tab in the BookOrbit library browser's own book detail dialog.

↑ Top

Reader

Everything available inside the Codexa reader — EPUBs and comic books

Reader interface overview
Reader overview

Interface Overview

The reader has three main areas:

  • Header bar — buttons for TOC, bookmarks, highlights, search, jump, settings, fullscreen, and back to library. Can be set to auto-hide while reading. Search and annotation buttons are hidden when reading comics (image-only files have no text to select).
  • Reading area — book content rendered by CXReader, Codexa's custom engine. The left and right edges are tap/click zones for page navigation.
  • Status bar — configurable overlay slots at the top and bottom of the screen showing page numbers, progress, time estimates, and more.

Navigation

Tap / Click

  • Right half of the screen (configurable percentage) → next page
  • Left half of the screen (configurable percentage) → previous page

The centre of the screen is reserved for text selection and dictionary lookups.

Swipe (touch)

  • Swipe left → next page
  • Swipe right → previous page

Keyboard

KeyAction
/ Space / Page DownNext page
/ Page UpPrevious page
KToggle Table of Contents
IToggle Search
SToggle Settings
FToggle fullscreen
EscClose open panel — or return to library

Mouse Wheel

Enable mouse-wheel page turning in Settings → Device → Mouse wheel navigation.

Volume Keys (Android App)

Enable in Settings → Device → Volume key navigation. Swap the direction with Swap volume key direction.

Table of Contents

Table of contents sidebar
Table of contents

Press K or tap the TOC button (☰) in the header. The current chapter is highlighted. Tap any chapter to jump to it — the sidebar closes automatically.

Bookmarks

Bookmarks sidebar
Bookmarks panel
  • Tap the Bookmarks button (🔖) — the badge shows the count.
  • Click + to save your current position. The bookmark is labelled with the chapter title by default.
  • Tap any bookmark to jump to it; a Back / Accept button pair appears so you can return or confirm.
  • Rename a bookmark with the pencil icon; delete with ×.
  • Bookmarks are stored per user and available on all devices.

Highlights & Annotations

Annotation toolbar after text selection
Annotation toolbar
Annotations list sidebar
Annotations list

Creating a Highlight

  1. Select text by pressing and holding (mobile) or clicking and dragging (desktop).
  2. The annotation toolbar appears above or below the selection. On mobile, drag the native selection handles to adjust what's selected — the toolbar stays open and follows along.
  3. Tap a colour button (yellow, green, blue, pink) to save the highlight.

Tapping anywhere outside the selection clears it and closes the toolbar without saving anything.

For Chinese, Japanese, and Korean text, selection uses real word/character segmentation — see Chinese, Japanese & Korean Text for details.

Adding a Note

After selecting text, tap the pencil (✎) button in the toolbar. Type your note (up to 1000 characters) and click Save.

Viewing All Annotations

Tap the Highlights button in the header to open the annotations sidebar. All highlights are listed in reading order with colour indicator, highlighted text, and any attached note. Tap an entry to jump to its position.

Editing or Deleting a Highlight

Tap an existing highlight in the text. An edit sheet slides up from the bottom showing the highlighted text, a colour picker, an edit note button, and a delete button.

Dictionary Lookup from Selection

After selecting text, tap the magnifying glass (🔍) button in the toolbar to look up the selection without saving a highlight.

In-book search panel
Search panel

Press I or tap the search button. Type a word or phrase and press Enter. Results are grouped by chapter with surrounding context. Tap any result to jump to it. A Back / Accept button pair lets you return to your original position or confirm the jump.

Dictionary Lookup

Dictionary definition popup
Dictionary popup

Desktop: double-click a word to open the dictionary directly. To look up a selection, drag to select it and tap the dictionary icon in the bottom toolbar.
Mobile: long-press to start selecting text (drag the handles to adjust it), then tap the dictionary icon in the bottom toolbar — selecting text on its own never looks anything up automatically. A bottom sheet shows definitions from all enabled dictionaries.

Footnotes

Footnote popup
Inline footnote popup

Tap any footnote or endnote marker. The note content appears in a popup at the bottom of the screen — you don't need to leave your reading position. Tap × or outside the popup to dismiss.

Reading Progress & Session Recovery

Your reading position is saved automatically as you read. If you close the browser or app mid-chapter, a resume banner appears the next time you open the library. Tap Resume to jump back, or Dismiss to ignore it.

Resume closed book
Resume closed book

Finishing a Book

Pressing next page on the last page of a book shows a finished screen instead of doing nothing. It offers a button to return straight to the library. In e-ink mode the screen is rendered in matching black-and-white instead of color.

Jump to Position

Jump to position slider
Jump to position

Tap the percentage button (%) in the header. Drag the slider to any position. Chapter markers on the slider show chapter boundaries. Use the Previous / Next chapter buttons to jump to adjacent chapters.

Fullscreen Mode

Press F or tap the fullscreen button (▢) to hide all browser chrome. Press F again or Esc to exit. A small exit button also appears in the corner.

Sleep Timer

Tap the sleep timer button in the header (it can be hidden via Settings → Theme → Header buttons) to set a countdown. When the timer reaches zero, Codexa performs the action you chose. A small badge on the button shows the remaining time while a timer is running.

  • Presets: 5, 10, 15, 30, 45, or 60 minutes — tap a preset to start the timer.
  • Cancel: reopen the panel and tap Cancel timer to stop a running countdown.

Choose what happens when the timer ends:

End actionEffect
Dim screenFades a dark overlay over the page. Tap anywhere to dismiss it and keep reading. (Default.)
Close bookReturns to the library, saving your reading position first.
Turn off keep-screen-onReleases the screen Wake Lock so the device can sleep normally (use this alongside the Keep screen on device setting).

Reading Settings

Reader settings panel with tabs
Settings panel (⚙ button or S key)

Press S or tap the settings button (⚙). Settings are saved globally and apply to all books. Use Reset for this book at the top of the panel to clear any per-book overrides.

Theme Tab

Theme settings tab
Theme settings
Header button toggles
Header button toggles
  • Theme: Light, Sepia, Dark, Sepia Dark, Midnight, Nord, Custom. Selecting Custom reveals a background colour picker and a text colour picker.
  • Override book styles: forces the reader's fonts and colours on books with their own CSS.
  • E-ink mode: high-contrast black-and-white for e-ink displays.
  • Page border (book spine): shows a thin shadow along the centre spine in two-page spread mode.
  • Presets: save and switch between named settings profiles — see Presets.

Header buttons

Toggle individual buttons in the reader toolbar on or off. Hidden buttons are simply removed from the header; their features remain accessible elsewhere (e.g. the bookmarks panel). Available toggles:

  • Highlights — show/hide the annotations button.
  • Search — show/hide the in-book search button.
  • Percentage — show/hide the reading-progress percentage button.
  • Sync — show/hide the KOSync/progress sync button.
  • Sleep timer — show/hide the sleep timer button.
  • Fullscreen — show/hide the fullscreen toggle button.
  • Bookmark count badge — shows a small number badge on the bookmark button indicating how many bookmarks the current book has.
  • Highlight count badge — shows a small number badge on the highlights button indicating how many highlights the current book has.

Text Tab

Text settings tab
Text settings
  • Font: system fonts + any custom fonts uploaded by an admin.
  • Font size: 12–36 px.
  • Line spacing: 1.0–3.0.
  • Letter spacing: 0–10 px.
  • Paragraph indentation: toggle + depth slider (0.5–4 em).
  • Paragraph spacing: 0–3 em extra space between paragraphs.
  • Chapter heading spacing: compresses whitespace before headings.
  • Hide empty lines: collapses blank paragraphs.
  • Left-align text: disables CSS justification.
  • Word hyphenation: automatic hyphenation at line breaks; language-aware.
  • Bionic reading: bolds the first ~40% of each word to guide the eye.

Page Tab

Page layout settings tab
Page settings
  • Page layout: Single page or Two pages (spread — side-by-side like an open book).
  • Margins: horizontal margin between text and screen edge (0–120 px).
  • Auto-hide toolbar: hides the header while reading; reveal by moving the pointer to the top or tapping the top edge.
  • Screen edge padding: insets for each side to avoid curved edges and notches.

Page-Turn Animation

Choose how pages transition when you move forward or back. The setting is in the Page tab and applies to all books.

AnimationEffect
NoneInstant page change — no animation. Best for e-ink displays, where motion causes ghosting.
FadeThe new page cross-fades in. (Default.)
SlideThe page slides in from the side in the direction of travel.
PaperA paper-like sheet slides across, mimicking a physical page turn.
MomentumThe page moves with an eased, weighted motion that carries momentum.
ZoomThe new page scales in for a subtle depth effect.

Finger tracking (drag): available for the Paper and Momentum animations. When enabled, the page follows your finger (or pointer) as you drag across the screen, then completes or snaps back on release — so the turn feels directly connected to your gesture rather than a fixed animation. Toggle it on the row just below the animation picker.

E-ink tip Set the animation to None on e-ink devices. Animated transitions trigger repeated full-screen refreshes and leave ghosting on e-ink panels.

Device Tab

Device settings tab
Device settings
  • Keep screen on: prevents sleep using the browser WakeLock API (requires HTTPS).
  • Mouse wheel navigation: scroll wheel turns pages.
  • Portrait lock: locks orientation to portrait.
  • Volume key navigation (Android app only): hardware volume buttons turn pages.
  • Swap volume key direction (Android app only): reverses which button goes forward.
  • Skip progress check on open: opens the book from the beginning instead of the last position.
  • Skip auto-save on close: prevents position from being saved when leaving the reader.

Status Bar Tab

Status bar settings tab
Status bar settings

Place information overlays in up to six positions around the reading area: top-left, top-centre, top-right, bottom-left, bottom-centre, bottom-right.

[ top-left ]   [ top-centre ]   [ top-right ]
─────────────────────────────────────────────  ← separator (optional)

         [ book text ]

─────────────────────────────────────────────  ← separator (optional)
[ bot-left ]   [ bot-centre ]   [ bot-right ]

Available information items:

ItemDescription
Chapter page (X/Y)Current page and total pages in the current chapter
Book page (X/Y)Absolute page number across the whole book
Pages left in chapterRemaining pages until the end of the chapter
Pages left in bookRemaining pages in the entire book
Chapter progress %Percentage through the current chapter
Book progress %Percentage through the entire book
Time to end of chapterEstimated time to finish the chapter (from your reading speed)
Time to end of bookEstimated time to finish the book
Current timeSystem clock
Book titleTitle of the current book
Book authorAuthor of the current book
Chapter titleTitle of the current chapter
Chapter numberCurrent spine index and total spine items (e.g. 3/24)
BatteryDevice battery level as a percentage; icon changes to a charging symbol when plugged in (requires browser Battery Status API)
ConnectionShows Online or Offline depending on network connectivity

Additional options: Book progress bar and Chapter progress bar (thin lines at top or bottom), separator lines above/below the status area.

Status bar overlays in action
Status bar overlays

Dictionaries Tab

Dictionaries settings tab
Dictionary settings

Lists all installed dictionaries with their word count. Toggle each on/off, and use the up/down arrows to change lookup priority. Admins see an additional Upload button.

The first time you open a book with no dictionary preference saved yet, Codexa automatically enables dictionaries whose from language matches the book's own language (e.g. opening a Slovenian book enables Slovenian dictionaries instead of defaulting to English). After that, your choice is remembered per book.

KOReader Sync

Two tap areas in the bottom corners of the reading screen trigger a manual sync:

  • Bottom-left corner — pull the latest position from the sync server.
  • Bottom-right corner — push your current position to the sync server.

If the server position differs from your local position (e.g. you read on another device), a conflict resolution dialog asks which position to use: Stay here or Jump to X%. The same dialog appears when you open a book that was read further on another device in the meantime.

This is different from reconnecting after a period offline (e.g. waking the app from sleep): that case is fully automatic with no dialog — see Offline Reading for how it decides whether to push, pull, or do nothing.

Tap zones for KOReader Sync
Tap zones for KOReader Sync

Peek Mode

Open a book in Peek mode (from the Book Details dialog) to read without saving your position. Useful for reviewing a book without advancing your progress tracker.

A book in your BookOrbit library that you haven't added to Codexa yet can also be peeked directly — tap the peek button on its card. The file is fetched from BookOrbit into a temporary location and opened read-only; it is deleted automatically as soon as you close the reader. If the reader is closed abruptly (browser crash, force-quit) instead of normally, a background cleanup job removes the temporary file within a few hours regardless, so nothing is ever left behind on the server.

↑ Top

CXReader Engine

Codexa's own custom-built EPUB and comic rendering library

CXReader is the EPUB reading engine built entirely within Codexa. It is responsible for parsing, rendering, and paginating every book — reflowable EPUBs, fixed-layout EPUBs, and CBZ/CBR comics — with zero external dependencies.

Why We Built It

Codexa is meant to run everywhere, including older e-ink Android devices (notably the Chrome 83 WebView found on many BOOX and similar readers). Generic web reading engines tend to rely on virtual pagination — translateY transforms with clip-path masking — which clips lines at page boundaries on those WebViews and can make fetch() calls silently hang after a MutationObserver interaction. CXReader was designed from the ground up to avoid these problems, using native CSS multi-column layout so the browser fragments content correctly.

Building our own engine also let Codexa support things a generic EPUB renderer does not: CBZ/CBR comic books, pixel-accurate fixed-layout EPUBs, exact per-page position restore, and precise CFI annotations — all handled directly inside CXReader.

Engine Highlights

CapabilityHow CXReader handles it
Pagination engine Native CSS multi-column layout — the browser fragments content correctly, with no line clipping on e-ink WebViews
E-ink compatibility Built with legacy WebView quirks (Chrome 83) in mind; per-path workarounds baked in
Position restore accuracy Saves the exact page number per chapter; reopens on the precise page, with a percentage fallback if the layout changes
Fixed-layout EPUB Detects rendition:layout=pre-paginated and scales each spine item to fit the viewport with a CSS transform
Comic books (CBZ/CBR) Full support: image-only ZIP/RAR archives rendered full-screen, with a two-page spread on desktop
Annotation CFI precision Full DOM-range CFIs via CXReader's own generator/resolver — highlights land on the exact word, not just a text-search fallback
Font reflow Detects layout shifts from late-loading fonts and re-measures only when the content height actually changes
Dependencies Zero external rendering dependencies — all EPUB parsing is done client-side with JSZip and the browser's DOMParser

Exact Position Restore

When you turn a page, CXReader saves both the spine index (chapter) and the exact page number within that chapter to localStorage. On reopen, it restores to that precise page.

If the layout changes between sessions — for example because you changed the font size or the window was resized — the saved page may be out of range for the new layout. In that case CXReader falls back to the reading percentage, which lands close to the right place. Once you are reading again, the exact page is re-saved for the next open.

Fixed-layout EPUBs

Fixed-layout EPUBs are books where each spine item (page) has a declared pixel size and precise coordinate-based CSS — typical for manga, children's picture books, art books, and graphic novels in EPUB format. Standard reflowable rendering completely breaks these.

CXReader detects fixed-layout books via the rendition:layout = pre-paginated OPF metadata tag. When detected:

  • Each spine item is rendered in an iframe at its declared pixel dimensions (e.g. 1200 × 1600 px).
  • The iframe is scaled with CSS transform: scale() to fit the viewport — centred horizontally and vertically.
  • The reader's own CSS (fonts, margins, column layout) is not injected so the book's precise styling is preserved.
  • Every page advance moves to the next spine item — one item equals one page.
  • Reflowable EPUBs are completely unaffected.
↑ Top

BookOrbit Library

Browse, add, and peek books from a self-hosted BookOrbit server without leaving Codexa

If you self-host a BookOrbit server, Codexa can browse its entire library natively — a dedicated panel alongside your regular library and the Online library (OPDS) browser, purpose-built around BookOrbit's own organisation (libraries, smart scopes, collections, series, and authors) instead of generic OPDS folders. This is entirely optional and separate from BookOrbit Sync — you can browse without ever enabling extended sync.

BookOrbit library showing catalog entries
BookOrbit library with catalog navigation

Setup

BookOrbit version Requires BookOrbit v2.1.0 or higher.

Go to Settings → BookOrbit, enter your BookOrbit server URL, and click Test connection. No account credentials are required just to browse — only the server URL. Once saved, a BookOrbit entry appears in the left sidebar.

Browsing

Open the BookOrbit panel from the sidebar. A left-hand nav lists six sections:

  • Libraries — every BookOrbit library you have access to
  • Smart Scopes — BookOrbit's saved dynamic filters
  • Collections — your manually curated collections
  • Series — browse by series
  • Authors — browse by author
  • Book Search — search BookOrbit directly by title or author

Selecting an item on the left shows its books on the right, using the same grid density control and sort menu as the main library, plus a Default option that sends no sort override at all and just shows books in whatever order your BookOrbit server returns them — handy for collections you've already hand-ordered on the server. Your chosen sort order is remembered across visits. Each book card shows a Add to Codexa button (permanently downloads and imports the book) and, if it's already in your Codexa library, a badge instead. Cards for books already downloaded also link to the book's Book Details dialog, which includes a View on BookOrbit link that opens the book on your BookOrbit server in a new tab (or the system browser, if Codexa is installed as a PWA/app).

Peeking a Book

Every card also has a Peek button, even for books you haven't added to Codexa yet. See Peek Mode in the Reader section for how peeking an un-downloaded book works — in short, the file is fetched temporarily, opened read-only, and cleaned up automatically when you close the reader (or shortly after, if the tab was closed abruptly).

Collections

Click Collections on a book card to open the collection membership editor — a checklist of every BookOrbit collection you have. Tick or untick collections and click Save collections to update membership directly on the BookOrbit server, without needing to switch to BookOrbit's own web interface.

Sync to a Shelf

Open a Collection or Smart Scope and click Sync to a Codexa shelf to download every book it contains into a named shelf, exactly like OPDS Folder Sync. The shelf becomes linked — it shows the same top-of-library banner with an Open in BookOrbit link and a resync button, and re-running the sync only downloads books that are new since last time. Unlink a shelf from the shelf's edit dialog with Unlink from BookOrbit; the shelf and its books are kept.

While a shelf is linked to a collection or smart scope, a book's checkbox for it is locked in the book details Shelves tab — use the Collections tab to change its collection membership instead, or unlink the shelf to manage it by hand.

Mobile Drawer

On narrow screens, the BookOrbit nav collapses into an off-canvas drawer. Tap the button to slide it in, pick a section, and it closes automatically after you make a selection.

Reachability Warning

If Codexa cannot reach your saved BookOrbit server, a warning appears next to the BookOrbit entry in the sidebar, and in the reader if BookOrbit Sync is enabled. This does not affect KOReader/KOSync progress sync, which is entirely independent.

Opening a book card while browsing shows a detail dialog with two tabs: Details (description, genres, publisher, and other metadata) and Related. The Related tab is powered by BookOrbit's own recommendation engine and shows up to three sections — More in series, Also by this author, and Similar books — with cards that link out to the book's page on BookOrbit. This works for any book in the catalogue, including ones you haven't downloaded into Codexa yet.

↑ Top

BookOrbit Sync

Optional two-way sync of highlights, reading sessions, and book status/rating with a self-hosted BookOrbit server

If you self-host a BookOrbit server, Codexa can act as a second BookOrbit web reader — keeping your highlights, reading log, and reading status/rating in sync across all your clients (Codexa, BookOrbit's own web reader, and KOReader devices). This is entirely optional: users without a BookOrbit server are completely unaffected.

Prerequisite Save your BookOrbit server URL under Settings → BookOrbit first — see Settings. This field is independent of the URL saved under KOReader Sync → External KOSync Server. Requires BookOrbit v2.1.0 or higher.

What Syncs

DataDirectionTrigger
Highlights & notes Two-way Automatically when you open a book, create, edit, or delete a highlight
Reading sessions Codexa → BookOrbit Automatically when you close a book (session ≥ 60 s and ≥ 2 pages)
Live reading progress Codexa → BookOrbit Pushed on every KOReader/KOSync sync, not just when you close the book, so BookOrbit's own reader and other clients see your current position sooner
Read status Two-way Immediately when you change it in Codexa; adopted from BookOrbit when your local status is unset
Star rating Two-way Same as status

In addition to the per-action triggers above, Codexa runs a full background sweep every 30 minutes covering all books in your library. The sweep is paced to avoid hitting BookOrbit's rate limits.

Setup

  1. Go to Settings → BookOrbit and save your BookOrbit server URL, then click Test connection.
  2. Enter your BookOrbit account username and account password. These are your BookOrbit web login credentials — not the KOReader sync sub-account credentials.
  3. Tick Enable BookOrbit extended sync.
  4. Click Save. Codexa immediately runs a first sync across your library.
⚠ Account credentials vs. KOReader sync credentials BookOrbit Sync uses your BookOrbit web account login (the same username and password you use in BookOrbit's web reader). These may differ from the KOReader sync sub-account credentials you entered for progress sync. Enter the correct set for each.

To disable the sync, untick the toggle and save. From that point Codexa makes no further calls to BookOrbit, and deleting a highlight performs a permanent hard-delete again (instead of a soft-delete tombstone).

Book Status & Rating

Open the book info dialog (ℹ button) to set a book's status and rating. Changes are pushed to BookOrbit immediately. When a book has no local status or rating yet, Codexa adopts whatever BookOrbit has on the first sync.

Status valueShown as
Want to ReadBlue pill
ReadingGreen pill
ReadPurple pill
AbandonedGrey pill

The status pill and stars appear on the book card so you can see them at a glance without opening the info dialog.

Highlights & Annotations

Highlights you create in Codexa are pushed to BookOrbit automatically and appear in BookOrbit's own web reader (and on your KOReader device if you sync it to BookOrbit). Highlights created in BookOrbit's web reader are pulled into Codexa the next time you open the book.

  • Colors: yellow, green, blue, and pink map directly between Codexa and BookOrbit.
  • Notes: the note text attached to a highlight is synced both ways.
  • Deleting a highlight in Codexa when sync is enabled creates a soft-delete tombstone so the deletion is propagated to BookOrbit. The highlight disappears from the Codexa list immediately; BookOrbit removes it on the next sync. Deleting a highlight in BookOrbit's web reader removes it from Codexa on the next book open or background sweep.
  • A highlight must contain text — BookOrbit does not accept empty-text highlights. Image-only selections are not synced.
  • Highlights pulled from BookOrbit show a chapter-level location percentage (based on the CFI spine position) in the annotations sidebar.
CFI compatibility Codexa's CXReader engine produces standard EPUB CFI range positions, the same format BookOrbit's own web reader uses. No position translation is needed — highlights land on the exact same word on both sides.

Reading Sessions

A reading session is recorded whenever you close a book and the session lasted at least 60 seconds with at least 2 page turns. These thresholds filter out accidental opens and previews. Qualifying sessions are uploaded to BookOrbit's reading log and contribute to reading streaks, time-read statistics, and any other BookOrbit features that consume reading-session data.

Sessions are one-way (Codexa → BookOrbit) and are deduplicated: re-opening a book that was already synced never creates a duplicate session entry.

BookOrbit Dash

Once extended sync is enabled, a BookOrbit Dash item appears in the sidebar (same visibility rule as the BookOrbit Library item — hidden until sync is on, dimmed and unclickable while offline). It's a dedicated panel of account-wide reading stats, pulled live from BookOrbit's own dashboard API rather than anything Codexa stores locally:

  • Reading streak — current and longest streak, plus the last 7 days at a glance.
  • Yearly reading goal — books completed this year against your goal; click the card to set or change the goal directly from Codexa.
  • Currently reading — books BookOrbit considers in progress across your whole account, not just what's open in Codexa. Books already downloaded into Codexa link straight into the reader.
  • Library overview — total books, authors, series, and storage used across your whole BookOrbit library.
  • Highlight of the day — a highlight or note from your synced annotations, picked fresh each day.
Why this is different from Codexa's own Reading Statistics The Reading Statistics panel only knows about reading that happened inside Codexa. BookOrbit Dash reflects your whole BookOrbit account — including KOReader, Kobo, or manually logged sessions — because Codexa reports its own reading sessions to BookOrbit as part of extended sync (see Reading Sessions above).

Limitations & Notes

  • Book matching — a book must exist in your BookOrbit library for Codexa to sync it. Books only in Codexa (not imported from the BookOrbit OPDS catalog) are skipped; the server log shows "not in your BookOrbit library (skipping)" for them.
  • Rate limits — BookOrbit applies server-side rate limiting. Codexa paces its requests (150 ms between calls) and backs off automatically on HTTP 429 responses. The per-action trigger syncs only the affected book, never the entire library.
  • Status/rating conflict — when both Codexa and BookOrbit have a value, the local Codexa value wins. Remote changes are only adopted when the local field is empty (no last-edit timestamp is available from BookOrbit's API).
  • Annotation editing — only color, style, and note are editable after creation; the highlighted text range is immutable.
  • API coupling — BookOrbit Sync calls BookOrbit's internal web API. Updates to the BookOrbit server may occasionally require a matching Codexa update.
  • EPUB books only — comic books (CBZ/CBR) are not synced.
↑ Top

Comic Books

Read CBZ and CBR comic files alongside your EPUB library

Codexa supports the two most common digital comic formats. They appear in your library exactly like books and can be downloaded for offline reading, organised into shelves, and imported from OPDS servers.

Formats

FormatExtensionContainerNotes
CBZ .cbz ZIP archive of images Preferred format — stored directly on the server
CBR .cbr RAR archive of images Automatically converted to CBZ on the server at upload or import time. The original RAR is never stored.

Both formats are detected by their file signature (magic bytes), not just the file extension — so files with an incorrect extension are still handled correctly.

Supported image types inside the archive: JPEG, PNG, WebP, GIF, AVIF. Images are sorted by filename using natural (numeric) ordering, so page10.jpg sorts after page9.jpg.

Uploading & Importing

Direct Upload

Use the Upload button (⇧) in the library toolbar and select .cbz or .cbr files. Multiple files can be uploaded at once. CBR files are converted to CBZ automatically before being stored — you always get a CBZ in the library.

From OPDS

Navigate to a comic in the Online Library and click Add to library. Codexa downloads the file, detects CBR by its RAR signature even if the server reports the wrong content-type, and converts it to CBZ if needed. Folder sync works the same way — an entire OPDS comic folder can be synced to a shelf in one action.

Reading Comics

Open a comic the same way as any book. CXReader detects the CBZ format automatically and switches to image-display mode.

Single-Page Mode

By default one page is shown at a time, filling the reading area. Navigation works identically to books: tap/click the right half for the next page, left half for the previous page, or swipe left/right on touch screens.

Two-Page Spread (Desktop)

When Two pages layout is selected in Reader Settings → Page, two consecutive comic pages are shown side by side — just like a physical comic book spread. Each navigation step advances by two pages and always stays aligned to even-numbered boundaries (0+1, 2+3, 4+5, …) so spreads never get out of sync.

Background Colour

The background behind the image uses the same colour as the selected reader theme. In the default Light theme this is white; in Dark or Midnight themes it is dark/black. Switch to any theme you prefer — the comic background follows automatically.

Download Progress

Comic files are large. While downloading, Codexa shows the actual download percentage (Downloading file… 45%) instead of an animated ellipsis. On e-ink mode, the percentage updates at wider intervals (every 10%) to reduce screen refreshes.

What's Not Available for Comics

Because comic pages are images, the following text-based features are hidden when reading a comic:

  • In-book text search
  • Highlights & annotations
  • Dictionary lookup
  • Bionic reading
  • Font and text settings

Bookmarks, reading progress, offline download, shelves, and KOReader sync all work normally.

Metadata (ComicInfo.xml)

CBZ files can include a ComicInfo.xml file at the root of the archive. This is a widely-supported standard used by comic management tools such as Mylar3, ComicTagger, and Komga. Codexa reads the following fields from it:

ComicInfo.xml tagCodexa field
TitleBook title
SeriesSeries name
NumberSeries number (issue/volume)
SummaryDescription
Writer + PencillerAuthor (combined)
GenreGenre tags

The metadata is extracted both at upload time (server-side) and when the comic is opened in the reader (client-side). If ComicInfo.xml is absent, the archive filename is used as the title.

↑ Top