A minimalist book reader where ink meets moonlight. Crafted, quiet, literary.
Website: inkuna.app
One Rust core, two native shells. All non-UI logic (library database, import,
format detection, metadata, reading progress, search — later annotations and
sync) lives in Rust and is exposed to both platforms through
UniFFI. The core also owns the reader
itself: a layout engine that parses, styles, shapes, and paginates each
chapter into per-page glyph-run display lists, which the shells draw natively
(Core Text on iOS, Canvas.drawGlyphs on Android) and drive with their own
gesture and spring physics. Each shell is thin and fully native so the
reading experience feels at home on its platform.
core/ Rust workspace
crates/inkuna-content/ EPUB container: archive reads, OPF/spine, TOC
crates/inkuna-format/ import-side conversion (MOBI/AZW3/TXT -> EPUB)
crates/inkuna-engine/ reader layout engine: DOM -> style -> shape ->
paginate -> display lists (CJK + vertical writing)
crates/inkuna-core/ domain services: library, DB, import, search
crates/inkuna-ffi/ UniFFI surface -> Swift + Kotlin bindings
apps/ios/ UIKit shell (min iOS 18, Liquid Glass gated on iOS 26)
apps/android/ Jetpack Compose shell (minSdk 33, targetSdk 37)
assets/ brand assets (icon sources + Icon Composer layers)
scripts/ core cross-build + bindings generation + icon rasters
website/ Astro static site for inkuna.app (Cloudflare Pages)
docs/ project documentation
Formats: EPUB, MOBI, AZW3 (DRM-free), and TXT ship today — reflowable formats normalize to EPUB at import. PDF and CBZ/CBR comics are planned as fixed-layout formats with dedicated navigators. CJK typography — including vertical writing and CJK-aware search — is a first-class goal.
Requires the latest stable rustup toolchain (with iOS/Android targets), cargo-ndk, Xcode, XcodeGen, Android SDK + NDK, and a current JDK.
# Core (tests)
cd core && cargo test
# iOS
./scripts/build-core-ios.sh
cd apps/ios && xcodegen generate && open Inkuna.xcodeproj
# Android
./scripts/build-core-android.sh
cd apps/android && ./gradlew assembleDebuginkuna.app is an Astro site in website/ (fully static
output, zero client JS) on Cloudflare Pages. Pushes to main that touch
website/ build and deploy automatically via GitHub Actions; locally, run
pnpm install, then pnpm dev / pnpm build inside website/. pnpm is the
only supported package manager here — the pinned version comes from the
packageManager field in website/package.json (corepack enable pnpm once,
and the right version is fetched for you), and pnpm-lock.yaml is the
committed lockfile.
Releases are tag-driven, one tag per platform: ios-vX.Y.Z+N and
android-vX.Y.Z+N (X.Y.Z marketing version, N monotonic build number).
scripts/bump-version.sh <component> <major|minor|patch> [--tag] bumps a
component's version and mints the tag; pushing the tag builds the Rust core
and shell in CI, generates release notes from the commit log, and publishes
(TestFlight for iOS, a GitHub release with the APK for Android).
See CONTRIBUTING.md. Pull requests require a signed Contributor License Agreement.