- Rust 84.1%
- Kotlin 4.9%
- Shell 4.5%
- JavaScript 3.1%
- Swift 2.8%
- Other 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
Build and Push iOS App / build-ios (push) Waiting to run
Build and Push macOS Binary / build-macos (push) Waiting to run
Check kreeader-ui pointer sync / check-ui-sync (push) Failing after 2s
Build on minor version change / version-build (push) Successful in 3s
Build and Push Linux (Arch) Binary / build-arch (push) Failing after 1m32s
Build and Push Windows Binary / build-windows (push) Successful in 6m18s
Build and Push Android Binary / build-android (push) Successful in 12m34s
|
||
| .claude | ||
| .forgejo | ||
| .github/workflows | ||
| docs | ||
| e2e | ||
| kreeader-ui@f91799dff7 | ||
| packaging/systemd-user | ||
| roadmap/overnight-review | ||
| scripts | ||
| src-tauri | ||
| tauri-plugin-tv-display | ||
| .gitignore | ||
| .gitmodules | ||
| build.sh | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.js | ||
| README.md | ||
Kreeader client
This repository contains the Tauri 2 desktop, mobile, and TV wrapper for Kreeader. The Svelte browser UI
lives in the kreeader-ui git submodule. This repository owns the native Rust shell in src-tauri/,
platform packaging, CI, and the combined build driver in build.sh.
The configured product name is Kreeader, the application identifier is in.jiggl.kreeader, and the main
binary is kreeader-client.
Server connection
The UI communicates directly with a kreeader-server over HTTP. On first run, the application opens Settings so the server URL can be configured.
The server broadcasts the _kreeader._tcp mDNS service for clients that browse for it. This desktop
application itself is configured by URL.
Development quickstart
Initialize the UI submodule and install the wrapper dependencies:
git submodule update --init
npm install
Build the UI and native application for the current machine:
./build.sh
For development, start the UI development server on port 1420 and run Tauri against a running kreeader-server:
npm --prefix kreeader-ui run dev
npm run tauri dev
The development server URL and port are configured in tauri.conf.json.
Building
The build driver accepts an optional target and subcommand:
./build.sh [--target <os>[-<arch>]] [subcommand]
Supported targets are:
localis the default and builds for the current machine.linuxbuilds the Linux application. Linux bundle targets are deb and rpm.macos-aarch64andmacos-x86_64build on a Mac with the Xcode Command Line Tools installed.windowscross-compiles from Linux forx86_64-pc-windows-msvcusingcargo-xwinand the NSISmakensistool.android-aarch64builds a debug APK and requires the Android NDK.iosrequires a Mac and an Apple signing identity.
Build only the browser bundle at kreeader-ui/dist with:
./build.sh web
Always build the native application through npx tauri build, npm run tauri build, or build.sh. Do not
use bare cargo build. The Tauri CLI enables the custom-protocol feature that embeds the built frontend;
a bare Cargo build produces an application with no UI at runtime.
Rust shell
The native shell is in src-tauri/src/ and is thin by design. UI-to-server traffic uses plain HTTP. The
opener plugin hands /debug deep links to the system browser.
- Phone remote: A small LAN web server listens on port 38400 (
REMOTE_PORTinlib.rs). A single-use QR token authenticates a temporary WebSocket used for WebRTC signaling. Commands then travel over the encrypted peer-to-peer data channel and feed the same frontend handler used for server-relayed commands. The builtkreeader-uidistribution is embedded into the binary at compile time withinclude_dir, so this LAN server can serve the SPA's/#/remoteand/#/tvroutes to a phone browser. Linux desktop builds advertisedirectmode because WebKitGTK has noRTCPeerConnection; commands are relayed over the signaling WebSocket. All other platforms use the WebRTC DataChannel. - Cast sender:
cast.rsimplements the desktop-only Google Cast sender withrust_cast. It discovers Chromecast targets by browsing_googlecast._tcpwithmdns-sd. On Android and iOS,rust_castcannot cross-compile because ofopenssl-sys, socast_stub.rssupplies a same-shaped no-op API. Call sites and the Tauri command list remain identical across platforms. - TV display plugin:
tauri-plugin-tv-display/is an in-repository Tauri v2 plugin, mobile-only and gated to Android and iOS insrc-tauri/Cargo.toml. It gives phone and tablet builds a second "10-foot" screen. Its native Google Cast sender uses Kotlin or Swift with the Cast SDK, and its message-channel schema matches the desktopcast.rssender. Native external-display support uses Android Presentation with WebView or an iOS secondUIWindowwithWKWebView, loading the UI's/#/tvroute. - DRM:
drm.rsis the client-side unwrap and decrypt counterpart to kreeader-server'sdrm/drm.gowire format. - Release integrity:
fingerprint.rsandhandshake.rsimplement per-machine fingerprint hashing and a startup handshake with the server'sPOST /api/client/handshake. A 403 forrelease_revokedorfingerprint_bannedhard-blocks the application with a nativetauri-plugin-dialogdialog. - Screenshot blocking:
screenshot_block.rscontains per-platform enforcement. - Token vault:
tauri-plugin-strongholdprovides encrypted-at-rest local storage for session and OIDC tokens through one implementation shared by desktop, Android, and iOS.
Continuous integration
Forgejo workflows are stored in .forgejo/workflows/:
build-arch.ymlbuilds Linux on every branch push and ondesktop-v*tags using a self-hosted, containerized runner.build-windows.ymlcross-compiles the Windows binary from Linux withcargo-xwinand NSIS; no native Windows machine is involved.build-macos.ymlbuilds macOS aarch64 on a self-hosted macOS runner for pushes tomasteranddesktop-v*tags.build-android.ymlbuilds a debug APK on a self-hosted Android runner using a prebuilt SDK and NDK image.build-ios.ymlruns the iOS build on the macOS runner for pushes tomaster. It is currently expected to fail at the sign/export stage because Apple signing secrets are not wired in; the workflow keeps that failure visible as its own row.check-ui-sync.ymlfails when this repository'skreeader-uisubmodule pointer differs from kreeader-server's. Both superprojects must track the same UI commit.release.ymlcreates a Forgejo release when adesktop-v*tag is pushed. The tag must match the version inpackage.json.version-build.ymlcomputes SemVer{MAJOR}.{MINOR}.{REV}withscripts/compute-version.sh.MAJORcomes from lightweightmajor-Ntags;MINORandREVuse commit-count arithmetic. It dispatches the Arch package build only whenMINORorMAJORchanges.
Testing
The Playwright end-to-end suite is configured by playwright.config.js and stored in e2e/. Run it with:
npm run test:e2e
Repository layout
kreeader-ui/— Svelte UI submodule; itsdist/is consumed by Tauri and can be embedded by the server.src-tauri/— native Rust shell and Tauri configuration.tauri-plugin-tv-display/— mobile Tauri plugin for Cast and external displays.build.sh— combined frontend and platform-aware native build driver.packaging/— platform packaging files.scripts/— repository build and version scripts.e2e/— Playwright end-to-end tests.