Cobalt: apps and an SDK for Kobo e-readers
Your Kobo can run apps now.
Cobalt is an open-source application platform for Kobo e-readers: a launcher, a signed App Store, a Rust SDK, and a runtime that keeps every app in its own unprivileged process.
Install it once over USB. Every app after that installs, updates and removes on the reader itself, over Wi-Fi. A reboot returns to the stock Kobo reader.
Install on your Kobo<br>Read the source
The launcher on a Kobo Clara BW.
Not affiliated with Rakuten Kobo
Recorded on-device at 3× speed. Watch as video.
Running on a Kobo.
Every app is a static ARM binary running as its own unprivileged process on stock hardware. The App Store installs, updates and removes them over Wi-Fi, with signatures verified before anything launches.
arXiv papers and coding agents, on the panel.
These are photographs of the device, not simulator captures. The arXiv app reads the HTML rendering arXiv publishes for every paper since December 2023: abstracts, sections, math and result tables, paginated for the panel.
A preprint, page 8 of 54, on the panel.
A results table from the same paper.
Math notation and a numbered algorithm.
Sidekick showing a question from Claude Code, with tappable answers.
Sidekick paired over the local network, waiting for the next question.
Apps
The apps.
Every screenshot below is a capture from a Kobo Clara BW. Store apps version independently of the platform; the rest ship with the platform install.
Launcher
Opens installed apps and always keeps a route back to the Kobo reader.
App Store
Installs, updates, removes and reinstalls signed apps over Wi-Fi.
arXiv
Browses a subject's newest preprints and reads the full text on the panel.
Sudoku
Store-only by design: installing it proves delivery of an app the USB package never contained.
Morse
Sends a typed message in Morse on the front light, one letter across the whole panel.
Audiobook Studio
Researches, writes, narrates and plays an original audiobook.
Gutenbird
Reads any OPDS library: Project Gutenberg, Standard Ebooks, Open Library, or yours.
Hacker News
Top, New, Ask and Show stories with complete comment threads.
Feeds
Discovers a site's feed and presents its articles without the site's layout.
Daily Brief
Collects the day's stories in the background while you use another app.
AI Command Center
Asks a question and turns the answer into touch-friendly reading.
Sidekick
Approve or deny requests from coding agents, away from the keyboard.
Terminal
A panel-native shell with keys that send input immediately.
Components
The UI toolkit's controls, layouts, typography and states, on the panel.
Settings
Connectivity, hardware, and platform updates, kept separate from Store.
Todo
A persistent list with touch entry and completed-item states.
Tic-tac-toe
Two players, partial refreshes for individual cells.
Magnet
Locates the hall sensor behind the bezel and reports its changes.
The SDK
An app is one Rust file.
Implement KoboApp, describe screens declaratively, and the runtime handles layout, e-ink refresh planning, Back navigation and lifecycle.
Apps don't open device resources; they ask. Network, storage, audio, frontlight and Wi-Fi are capability-gated, and a refusal comes back as a value the app can handle.
E-ink UIText, tiles, dialogs, keyboards, pagination, partial refresh planning
SimulatorsBrowser and runtime simulators with layout diagnostics
Async workHTTPS, ranged downloads, cancellable tasks, scheduled wakes
StateAtomic per-app keyed storage
ShippingSigned static ARMv7 binaries, published when an app PR merges
kobo new my-app<br>cd my-app<br>kobo dev<br>Read the SDK docs
use kobo_sdk::{<br>ActionId, Context, KoboApp, ScreenBuilder,<br>};
#[derive(Default)]<br>struct Hello { taps: u32 }
impl KoboApp for Hello {<br>fn on_start(&mut self, ctx: &mut Context) {<br>self.show(ctx);
fn on_action(<br>&mut self, ctx: &mut Context, a: ActionId,<br>) {<br>if a == kobo_sdk::action_id("tap") {<br>self.taps += 1;<br>self.show(ctx);
impl Hello {<br>fn show(&self, ctx: &mut Context) {<br>let screen = ScreenBuilder::new("hello")<br>.top_bar("Hello")<br>.heading(format!("{} taps", self.taps))<br>.button("tap", "Tap me")<br>.build();<br>ctx.set_screen(screen);
fn main() {<br>let app = Hello::default();<br>let _ = kobo_sdk::run("hello", app);
The Store
Signed packages, verified before launch.
Store reads a signed catalog from a fixed GitHub release. Each package holds one ARM executable and a signed canonical manifest. The runtime verifies the catalog, the package, the installed manifest and the binary before an app runs.
App releases are independent of platform releases: merging an app PR builds it for ARM, signs it, and updates the catalog. No Cobalt version bump, no reinstall. The app simply appears in Store.
The Cobalt platform itself also updates over Wi-Fi, through Settings, on a channel separate from the app catalog. The USB cable is only ever needed once.
Install and catalog transactions are recovery-safe; an...