A cross platform desktop reading app, based on the Readium Desktop toolkit https://www.edrlab.org/software/thorium-reader/
Find a file
Weblate (bot) 5befb6403b
fix(l10n): updated translations via Weblate - Italian, French, Russian (PR #3499)
Co-authored-by: Veronica Fantini <veronica.fantini@edrlab.org>
Co-authored-by: Сергей <asvmail.as@gmail.com>
2026-04-16 16:09:18 +01:00
.flox fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
.github/workflows chore(CI): latest GitHub Actions for checkout and setup-node, also persist-credentials disabled (unnecessary) 2026-04-13 10:22:17 +01:00
.vscode chore(dev): navigator webview preload now always bundled to avoid require() node_modules, some script cleanup 2025-09-25 16:26:41 +01:00
changelogs chore(release): minor changelog update [skip ci] 2026-04-07 23:22:38 +01:00
docs NPM updates (should fix package-lock.json for missing CSS-Element-Queries GitHub-hosted package (r2-navigator-js ResizeSensor)) 2019-04-17 19:03:33 +01:00
external-assets Fix external dependencies of renderer 2017-10-31 10:32:42 +01:00
img chore(doc): README, architecture documentation (PR #1996) 2023-11-16 11:47:27 +00:00
resources fix: MacOS icon size ( PR #2453 Fixes #1664 ) 2024-06-16 20:24:24 +01:00
scripts chore(dev): NPX ==> npm exec --no --offline (@electron/fuses local node_modules installation dev NPM package dependency) [skip ci] 2026-04-15 20:43:02 +01:00
src fix(l10n): updated translations via Weblate - Italian, French, Russian (PR #3499) 2026-04-16 16:09:18 +01:00
test fix: inadvertently deleted custom profile ZIP in previous commit [skip 2025-12-10 08:42:26 +00:00
.editorconfig Use last version of eclint to be able to add comment in source code 2017-05-15 16:21:45 +02:00
.envrc chore(dev): introduce shell.nix and .envrc with direnv [skip ci] 2025-07-22 18:52:57 +02:00
.eslintignore chore: migration of r2-xxx-js packages into Thorium's source tree (PR #3383) 2026-02-09 20:19:01 +00:00
.eslintrc.js chore: migration of r2-xxx-js packages into Thorium's source tree (PR #3383) 2026-02-09 20:19:01 +00:00
.gitignore fix(customization): improve profile packaging command line build chain (PR #3280) 2025-11-04 18:29:38 +01:00
.npmignore chore(dev): Zed and Flox ignores, also removed obsolete postinstall scripts in src/package.json (aligned with top-level package.json) 2024-11-27 15:07:41 +00:00
.npmrc feat(highlights): new text decoration "outline" (border style) in addition to solid background + underline + strikethrough (updated NPM packages, notably the navigator component which implements the highlights/annotations engine) 2024-02-18 12:38:40 +00:00
.nvmrc fix(doc): NodeJS and NPM versions, NVM usage (Fixes #2929) [skip ci] 2025-04-16 09:49:59 +01:00
.prettierignore chore(NPM): package dependencies update, notably Electron 40 NodeJS 24 2026-02-07 22:31:09 +00:00
.prettierrc.js chore(dev): replace deprecated TSLint with ESLint + Prettier (PR #1374 Fixes #625 ) 2021-02-12 10:41:54 +00:00
.stylelintrc.json feat!(GUI): refactored user interface (PR #2052) 2024-04-20 10:10:39 +01:00
.yarnrc Never install optional packages 2017-07-07 16:39:36 +02:00
CHANGELOG.md feat(dev): CHANGELOG re-organisation 2019-09-05 19:12:25 +01:00
container.sh chore(dev): Apple Container Docker memory bump and shutdown builder to give the runner more resources [skip ci] 2026-04-03 18:55:56 +01:00
customization-profile-public-key-pair.js fix(lint): minor code formatting issue [skip ci] 2025-12-09 15:23:14 +01:00
docker.sh chore(dev): Docker script with ARCHI uname override [skip ci] 2025-12-09 23:21:02 +01:00
Dockerfile fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
eslint-local-rules.js chore(NPM): package updates, notably Typescript 4.2 which requires significant update of "typed" Redux Saga, opportunity to cleanup codebase (PR #1403 ) 2021-02-26 15:24:46 +00:00
eslint.config.mjs chore: migration of r2-xxx-js packages into Thorium's source tree (PR #3383) 2026-02-09 20:19:01 +00:00
jest.config.js chore(NPM): updated packages, moved TypeScript Go compiler out of start:dev:quick to avoid arm64/x64 compatibility issues when testing in cross-compiled environments (rm -rf node_modules/electron && npm i electron --arch=x64 --cpu=arm64) 2025-06-12 10:56:06 +01:00
latest.json chore(release): latest.json [skip ci] 2026-04-09 01:37:03 +01:00
LICENSE Initial commit 2017-03-20 11:57:57 +01:00
package-linux_ARM64.sh fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
package-linux_x64.sh fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
package-lock.json chore(NPM): updated package dependencies (checked with SFW Socket Security Firewall and NPM Audit) 2026-04-14 07:00:00 +01:00
package-mac-skip-notarize_ARM64.sh fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
package-mac-skip-notarize_x64.sh fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
package-win_ARM64.sh fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
package-win_x64.sh fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
package.json chore(dev): NPX ==> npm exec --no --offline (@electron/fuses local node_modules installation dev NPM package dependency) [skip ci] 2026-04-15 20:43:02 +01:00
README.md fix(doc): NodeJS and NPM versions, NVM usage (Fixes #2929) [skip ci] 2025-04-16 09:49:59 +01:00
shell.nix chore(dev): introduce shell.nix and .envrc with direnv [skip ci] 2025-07-22 18:52:57 +02:00
tsconfig-cli.json fix(dev): Typescript esModuleInterop declare module vs. namespace, Slugify.d.ts [skip] 2026-03-14 12:47:41 +00:00
tsconfig-customization.json chore(NPM): package dependencies updates, notably latest TypeScript with a few breaking changes (moving towards Go implementation which we have been aligning with for several months now, but WebPack's ts-loader needs a temporary patch until fixed upstream) 2026-03-26 13:22:54 +00:00
tsconfig-fail.json fix: stricter TypeScript and TSLint code checks (PR #404) 2019-08-06 13:50:01 +01:00
tsconfig.json chore(dev): minor TypeScript config update dom.iterable is now included in dom lib [skip ci] 2026-03-26 20:01:51 +00:00
typings.d.ts fix: custom profile private signing key WebPack "define" plugin and Terser minifier was resulting in const var=null&&VALUE; without dead code elimination 2026-03-06 18:37:37 +00:00
webpack.config-preprocessor-directives.js fix(dev): GitHub Actions Workflow CI YAML script with GITHUB_TOKEN forwarded to 'env' and associated 'permissions' now not hoisted to job anymore, but scoped to step 2026-04-13 10:16:38 +01:00
webpack.config.js fix(PDF): using preload to extract PDF cover image (contextIsolation and sandbox security) 2025-09-25 11:49:30 +01:00
webpack.config.main.js chore(NPM): package updates, workaround for proxy-agent incompatible ESM module exports/imports syntax in package.json (for externals from main.js Webpack bundle) 2026-03-14 15:40:46 +00:00
webpack.config.preload.js chore: migration of r2-xxx-js packages into Thorium's source tree (PR #3383) 2026-02-09 20:19:01 +00:00
webpack.config.renderer-library.js chore: migration of r2-xxx-js packages into Thorium's source tree (PR #3383) 2026-02-09 20:19:01 +00:00
webpack.config.renderer-pdf-extract.js chore: migration of r2-xxx-js packages into Thorium's source tree (PR #3383) 2026-02-09 20:19:01 +00:00
webpack.config.renderer-pdf.js chore: migration of r2-xxx-js packages into Thorium's source tree (PR #3383) 2026-02-09 20:19:01 +00:00
webpack.config.renderer-reader.js chore: migration of r2-xxx-js packages into Thorium's source tree (PR #3383) 2026-02-09 20:19:01 +00:00

Thorium Reader

Thorium Reader is an easy to use EPUB reading application for Windows 10/10S, MacOS and Linux. After importing e-books from a directory or OPDS feed, you'll be able to read on any screen size, customize layout settings, navigate via the table of contents or page list, set bookmarks ... A great care is taken to ensure the accessibility of the application for visual impaired people using NVDA, JAWS or Narrator.

Free application. No ads. No private data flowing anywhere.

This project is in constant evolution, corrections and new features will be added soon and your support is welcome for that. The application is based on the open-source Readium Desktop toolkit.

More information can be found in the Landing page, within the online support documentation. Users can Add Documentation catalog to Thorium (OPDS link) or browse English documentation inline within the Readium web reader.

It is currently localized in following 28 languages:

  • (en) English
  • (fr) Français (French)
  • (fi) Suomi (Finnish)
  • (de) Deutsch (German)
  • (es) Español (Spanish)
  • (nl) Nederlands (Dutch)
  • (ja) 日本語 (Japanese)
  • (ka) ქართული (Georgian)
  • (lt) Lietuvių (Lithuanian)
  • (pt-BR) Português Brasileiro (Portuguese - Brazil)
  • (pt-PT) Português (Portuguese - Portugal)
  • (zh-CN) 简体中文 - 中国 (Simplified Chinese - China)
  • (zh-TW) 繁體中文 - 台灣 (Traditional Chinese - Taiwan)
  • (it) Italiano (Italian)
  • (ru) Русский (Russian)
  • (ko) 한국어 (Korean)
  • (sv) Svenska (Swedish)
  • (ca) Catalan
  • (gl) Galician
  • (eu) Euskadi (Basque)
  • (el) ελληνικός (Greek)
  • (bg) български (Bulgarian)
  • (hr) Hrvatski (Croatian)
  • (da) Dansk (Danish)
  • (sl) Slovenščina (Slovene)
  • (cs) čeština (Czech)
  • (ar) عَرَبِيّ (Arabic)

Since february 2025 we use Weblate project Thorium as the main tool for localisation. The following bar chart shows the translation status that is available from weblate.

Translation status

More information on translation process can be found in the dedicated translation page of the support website.

library publication info reader

Prerequisites

  1. NodeJS 22 (check with node --version)
  2. NPM 11 (check with npm --version)

TIP: the default version of NPM that ships with the NodeJS installer may be slightly old, so make sure to update with npm i -g npm@latest, or nvm install-latest-npm if you are an NVM user.

Technologies

  • typescript
  • electron
  • reactjs
  • redux
  • saga
  • i18next

Quick start

Install dependencies

  • npm install --foreground-scripts (or npm ci --foreground-scripts): initialize local node_modules packages from dependencies declared in package.json (this will also automatically call a long-running compilation stage in npm run postinstall)
  • in case of failure to NPM "install" because of "Divina player" SHA integrity mismatch, please try running the following command in your shell: node scripts/package-lock-patch.js && cat package-lock.json | grep -i divina-player-js

Start application in development environment

(with hot-reload dev server, web inspectors / debuggers)

  • npm run start:dev (or npm run start:dev:quick to bypass TypeScript checks / launch the app faster)

Start application in production environment

  • npm start (or npm run start)

Build installers

  • npm run package:win or npm run package:mac or npm run package:linux

Code Signing information: https://github.com/edrlab/thorium-reader/wiki/Code-Signing

Proxy server support

The HTTPS_PROXY, HTTP_PROXY, and NO_PROXY environment variables are used to configure the behavior of a client application when making HTTP or HTTPS requests through a proxy server.

  • HTTPS_PROXY: Specifies the proxy server to use for HTTPS requests. The value should be in the format http://proxy.example.com:8080.
  • HTTP_PROXY: Specifies the proxy server to use for HTTP requests. The value should be in the format http://proxy.example.com:8080.
  • NO_PROXY: Specifies a comma-separated list of hostnames or IP addresses that should not be proxied. This is useful for excluding local or intranet addresses from being proxied.

When these environment variables are set, the client application will automatically use the specified proxy server for HTTP or HTTPS requests, unless the request is for a hostname or IP address listed in the NO_PROXY variable.

we used proxy-agent package from TooTallNate (https://github.com/TooTallNate/proxy-agents/tree/main/packages/proxy-agent)

see https://www.npmjs.com/package/proxy-from-env#environment-variables for more information.

LCP support in Thorium Reader

Thorium Reader supports LCP-protected publications via an additional software component which is not available in this open-source codebase. When Thorium Reader is compiled from the open-source code without the additional production-grade library, the application can only load publications protected with the LCP "Basic Encryption Profile". For example, licenses generated by the open-source LCP server written in Go, without the patch that enables production-grade LCP Encryption Profiles.

In order to create a production-grade LCP-compliant variant / derivation of Thorium Reader (known as a "fork"), additional confidential software components and processes must be integrated in the custom application's build / release workflow. This represents a non-trivial amount of time and effort, as well as close collaboration between the fork's development team and EDRLab's technical staff. To cover operational costs, EDRLab charges a maintenance fee. Feel free to contact EDRlab to discuss your requirements.

Command line

thorium <cmd> [args]

Commands:
  thorium opds <title> <url>  import opds feed
  thorium import <path>       import epub or lpcl file
  thorium read <title>        searches already-imported publications with the
                              provided TITLE, and opens the reader with the
                              first match
  thorium [path]              import and read an epub or lcpl file     [default]
  thorium completion          generate bash completion script

Positionals:
  path  path of your publication, it can be an absolute, relative path  [string]

Options:
  --version  Show version number                                       [boolean]
  --help     Show help                                                 [boolean]

[DEV] Architecture

Thorium-reader is composed of 3 parts:

  • One node.js main process (electron back-end)
  • One library window (chromium renderer)
  • One to N reader window(s) (chromium renderer)

Each part runs a model-controller and a view for the renderer process.

  • the model is a state container with Redux. It's based on flux architecture
  • the controller is a middleware from Redux named Redux-saga. It handles all side effects and application behaviour.
  • the view for the rendering is React with class components

To link these 3 parts we use:

Diagram

Model View Controller Architecture

MVC

architecture diagram

API Concept

To have a POST request from a renderer process to the main process, we use the notion of API. It's not an http API but an RPC encapsuled one, to redux/redux-saga logic with Action and Reducer.

Here is a diagram of the communication:

api

Src:

  • src/main/redux/sagas/api/api.ts
  • src/common/redux/actions/api/index.ts
  • src/renderer/common/redux/reducers/api.ts

At the moment there are 17 API endpoints from (src/main/redux/sagas/api):

library:

  • apiapp:
    • apiapp/search : search a library from apiapp protocol
  • browser:
    • httpbrowser/browse : browse and parse an opds URL
  • opds:
    • opds/getFeed : get an opdsFeed with its identifier
    • opds/findAllFeed: get all opdsFeed saved
    • opds/deleteFeed: delete an opdsFeed with its identifier
    • opds/addFeed: add an opdsFeed
    • opds/getUrlWithSearchLinks: get the search URL from an opdsFeed
  • publication: (src/common/api/interface/publicationApi.interface.ts)
    • publication/get: get a publicationView from id
    • publication/delete: delete a publicationView from id
    • publication/findAll: get all publicationView
    • publication/findByTag: get all publicationView from a specific tag string
    • publication/updateTags: update tags list from a publication
    • publication/importFromLink: import a publication from an URL
    • publication/importFromFs: import a publication from a fileSystem path
    • publication/search: search publication from a query text
    • publication/searchEqTitrle: search publication by title matching
    • publication/exportPublication: export publication to the fileSystem

ACTION-REDUCER

From the main-process to the renderer-process, or from the renderer-process to the main-process.

List of all Actions in place (src/common/redux/actions):

  • auth: opds authentication
    • cancel
    • done
    • wipeData
  • catalog
    • getCatalog: ask to rehydrate catalogView in the libraryState
    • setCatalogView: response from getCatalog
    • setTagView: rehydrate tagStringView in the libraryState
  • dialog: modal dialog view in library,reader
    • closeRequest
    • openRequest
    • updateRequest
  • download: download queue in library
    • abort
    • done
    • progress
  • history: history opds feed
    • pushFeed
    • refresh
  • i18n
    • setLocale
  • import
    • verify: import verification process
  • keyboard: keyboard shortcut
    • reloadShortcut
    • setShortcut
    • showShortcut
  • lcp
    • renewPublication
    • returnPublication
    • unlockPublicationWithPassphrase
    • userKeyCheckRequest
  • load: main proceess busy or not
    • busy
    • iddle
  • net (not used)
  • reader
    • attachMode
    • clipboardCopy
    • closeRequest
    • closeRequestFromPublication
    • configSetDefault
    • detachModeRequest
    • detachModeSuccess
    • fullScreenRequest
    • openRequest
    • openError
    • setReduxState: trigger app persistence
  • session: saved session
    • enable
  • toast: toast notification library,reader
    • close
    • open