KindleJoy turns a jailbroken Kindle into a remotely managed e-ink display. Upload an image from a browser, and the Kindle client fetches and renders it with FBInk without needlessly refreshing an unchanged screen.
KindleJoy/
├── apps/
│ └── dashboard/ Flutter web app for selecting and publishing images
├── clients/
│ └── kindle/ Rust client and Kindle launcher script
├── services/
│ └── api/ Rust HTTP API, image processing, and token tooling
├── docs/
│ └── architecture.md Component boundaries and request flow
├── .env.example Safe local-server configuration template
├── Cargo.toml Rust workspace definition
└── Cargo.lock Locked Rust dependency graph
apps, clients, and services own deployable components. Shared Rust build
configuration lives at the repository root. The Actix service follows a
controller/service layout: config.rs loads runtime settings, controllers/
owns HTTP handlers, routes/ registers endpoints, services/ contains image
work, and libraries/ holds cross-cutting authentication helpers. Generated
output, local images, and secrets stay untracked.
The Kindle client uses the same responsibility-based split: config.rs loads
device settings, services/ owns polling, atomic screen storage, and FBInk
rendering, while libraries/ validates downloaded PNG content.
- Rust 1.88 or newer with Cargo.
- Flutter SDK for the dashboard.
- A jailbroken Kindle with FBInk and SSH access for the device client.
Clone the repository, then create private local configuration from the template:
git clone https://github.com/manav1999/KindleJoy.git
cd KindleJoy
cp .env.example .envEdit .env and replace both placeholder secrets. Keep this file private.
Generate strong values, for example:
openssl rand -hex 32Build the dashboard once:
cd apps/dashboard
flutter pub get
flutter build web --release
cd ../..Load the environment and run the API from the repository root:
set -a
. ./.env
set +a
cargo run --release -p roomboard-server --bin roomboard-serverOpen http://localhost:8080. Enter UPLOAD_TOKEN in the dashboard, upload
a PNG, JPEG, GIF, or WebP image (up to 10 MiB), and it will be normalized to a
600 × 800 grayscale PNG at screen.png.
For a physical Kindle connected through USBNetwork, use your computer's
USB-network address in clients/kindle/config.env as SCREEN_URL, such as
http://192.168.15.201:8080/screen.png.
Create a device JWT with the same JWT_SECRET and DEVICE_ID from .env:
set -a
. ./.env
set +a
cargo run --quiet -p roomboard-server --bin create-tokenBuild a static ARMv7 binary for most modern jailbroken Kindles:
rustup target add armv7-unknown-linux-musleabihf
cargo zigbuild --release -p kindle-client --target armv7-unknown-linux-musleabihfCopy target/armv7-unknown-linux-musleabihf/release/kindle-client and
clients/kindle/run.sh to /mnt/us/extensions/roomboard/ on the Kindle.
Copy clients/kindle/config.env.example to
/var/local/roomboard/config.env, add the server URL and JWT, and run the
launcher. Detailed component boundaries are in
docs/architecture.md.
This repository is intentionally a small Rust-and-Flutter playground. Start with the documentation index, which links the architecture, API, Kindle deployment, Flutter BLoC, image pipeline, and Rust walkthrough.
Run these from the repository root:
cargo test --workspace
cd apps/dashboard
flutter analyze
flutter testThe Kindle endpoint accepts only a JWT signed by your server secret. The
dashboard uses a separate upload token. Do not commit .env, device tokens,
or generated images. Use HTTPS and a reverse proxy before making the server
available outside a trusted network.
KindleJoy is available under the MIT License.