1
0
Files
kobopatch-webui/README.md

8.1 KiB

KoboPatch Web UI

Important

This is an experiment, mostly created with the help of Claude and some very precise instructions. It currently only supports the latest version of Kobo's software, and only for the Kobo Libra Color, Kobo Clara Color and Kobo Clara BW models. Further support may be added at a later date.

A web application for customising Kobo e-readers. It supports two modes:

  • NickelMenu — installs NickelMenu with an optional curated configuration (custom menus, fonts, screensavers, UI tweaks). Works with most Kobo devices regardless of software version. Can also remove NickelMenu from a connected device.
  • Custom patches — applies community kobopatch patches to your Kobo's system software. Requires a supported software version and device model.

The app uses the File System Access API (Chromium) to interface with connected Kobo devices, or falls back to manual model/software version selection with a downloadable ZIP on other browsers.

Fully client-side — no backend needed, can be hosted as a static site. Patches are community-contributed via the MobileRead forums and need to be manually updated when new Kobo software versions come out.

Note

This project is not affiliated with Rakuten Kobo Inc. Patching modifies system files on your Kobo and will void your warranty. If something goes wrong, you may need to manually reset your device.

User flow

  1. Connect or download — auto-detect your Kobo via File System Access API on Chromium, or choose manual download mode (any browser)
  2. Choose mode — NickelMenu (install/configure/remove) or custom patches
  3. Configure — for NickelMenu: select install options (fonts, screensaver, tab/homescreen tweaks) or removal; for patches: enable/disable patches (or select none to restore original software)
  4. Review — confirm your selections before proceeding
  5. Install — write directly to the device (Chromium auto mode) or download a ZIP/tgz for manual installation

File structure

web/public/                     # Webroot — serve this directory
  index.html                    # Single-page app, multi-step wizard
  css/
    style.css
  js/
    app.js                      # Step navigation, flow orchestration, firmware download with progress
    kobo-device.js              # KOBO_MODELS (serial prefix → name), FIRMWARE_DOWNLOADS (version+prefix → URL),
                                #   getDevicesForVersion(), getFirmwareURL(), KoboDevice class (File System Access API)
    nickelmenu.js               # NickelMenuInstaller: downloads NickelMenu.zip + kobo-config.zip, installs to
                                #   device or builds download ZIP, handles config file filtering and modification
    patch-ui.js                 # PatchUI class: loads patch zips (JSZip), parses YAML, renders toggle UI,
                                #   generates kobopatch.yaml config with overrides
    kobopatch.js                # KobopatchRunner: spawns Web Worker per build, handles progress/done/error messages
    patch-worker.js             # Web Worker: loads wasm_exec.js + kobopatch.wasm, runs patchFirmware(),
                                #   posts progress back, transfers result buffer zero-copy
    wasm_exec.js                # Go WASM support runtime (copied from Go SDK by setup.sh, gitignored)
    jszip.min.js                # Bundled JSZip library
  wasm/
    kobopatch.wasm              # Compiled WASM binary (built by build.sh, gitignored)
  patches/
    index.json                  # Contains a list of available patches
    patches_*.zip               # Each contains kobopatch.yaml + src/*.yaml patch files
  nickelmenu/                   # NickelMenu assets (built by nickelmenu/setup.sh, gitignored)
    NickelMenu.zip              # NickelMenu release
    kobo-config.zip             # Curated configuration files (fonts, screensaver, menu items)

nickelmenu/
  setup.sh                      # Downloads NickelMenu.zip and bundles kobo-config.zip from kobo-config repo

kobopatch-wasm/                 # WASM build
  main.go                       # Go entry point: jsPatchFirmware() → patchFirmware() pipeline
  go.mod
  setup.sh                      # Clones kobopatch source, copies wasm_exec.js
  build.sh                      # GOOS=js GOARCH=wasm go build, copies .wasm to web/public/wasm/
  integration_test.go           # Go integration test: validates SHA1 checksums of patched binaries
  test-integration.sh           # Downloads firmware and runs integration_test.go

tests/
  e2e/                          # Playwright E2E tests
    integration.spec.js         # Full browser tests: NickelMenu flows, custom patches, mock device
    playwright.config.js
    run-e2e.sh                  # E2E runner (downloads firmware, sets up NickelMenu assets, installs browser)

Adding a new software version

  1. Add the patch zip to web/public/patches/ and update index.json
  2. Add download URLs to FIRMWARE_DOWNLOADS in js/kobo-device.js (keyed by version then serial prefix)
  3. The Kobo CDN prefix per device family (e.g. kobo12, kobo13) is stable; the date path segment changes per release

Building the WASM binary

Requires Go 1.21+.

cd kobopatch-wasm
./setup.sh    # first time only
./build.sh    # compiles WASM, copies to web/public/wasm/

Setting up NickelMenu assets

nickelmenu/setup.sh

This downloads NickelMenu.zip and clones/updates the kobo-config repo to bundle kobo-config.zip into web/public/nickelmenu/.

Running locally

./serve-locally.sh

This serves the app at http://localhost:8888. If the WASM binary or NickelMenu assets haven't been set up yet, the script handles that automatically.

Testing

E2E tests (Playwright)

The E2E tests cover all major user flows:

  • NickelMenu — install with config (manual download), install NickelMenu only, remove option disabled without device
  • Custom patches — full patching pipeline, restore original firmware
  • With simulated Kobo Libra Color — install NickelMenu with config, remove NickelMenu, install custom patches, restore firmware

The simulated device tests mock the File System Access API with an in-memory filesystem that mimics a Kobo Libra Color (serial prefix N428, firmware 4.45.23646).

Custom patches tests download firmware 4.45.23646 (~150MB, cached in kobopatch-wasm/testdata/), enable a single patch, and verify SHA1 checksums of all 4 patched binaries. This specific combination is used because the author has tested it on an actual device.

cd tests/e2e
./run-e2e.sh

To run with a visible browser window:

./run-e2e.sh --headed

To slow down each action (500ms delay) for debugging:

./run-e2e.sh --headed --slow

Extra Playwright arguments can be passed after --:

./run-e2e.sh --headed --slow -- --grep "NickelMenu"

WASM integration test

Calls patchFirmware() directly in Go/WASM via Node.js:

cd kobopatch-wasm
./test-integration.sh

Output validation

The WASM patcher performs several checks on each patched binary before including it in the output KoboRoot.tgz:

  • File size sanity check — the patched binary must be exactly the same size as the input. kobopatch does in-place byte replacement, so any size change indicates corruption.
  • ELF header validation — verifies the magic bytes (\x7fELF), 32-bit class, little-endian encoding, and ARM machine type (0x28) are intact after patching.
  • Archive consistency check — after building the output tar.gz, re-reads the entire archive and verifies the sum of entry sizes matches what was written.

Credits

Built on kobopatch and NickelMenu by pgaskin. Uses JSZip for client-side ZIP handling. Software patches and discussion on the MobileRead forums.

License

MIT.