Directory structure
The application consists of a startup script and the main app directory:Core files
kanki.sh
The installation script that:- Copies the
kanki/directory from/mnt/us/documents/to/var/local/mesquite/kanki - Registers the app in Kindle’s SQLite database (
appreg.db) - Launches the app using LIPC (Lab126 Inter-Process Communication)
The app ID is
xyz.kurizu.kanki. This identifier is used throughout the Kindle system to reference the application.config.xml
Defines the widget configuration following Amazon’s Kindle widget specification. Key features:- Permissions: Local port access for file operations
- Network settings: User agent, connection limits, DNS configuration
- Cookie jar: Persistent cookies enabled
- Chrome settings: System search bar configuration
- Gestures: Tap and swipe support
- Resources: LocalStorage quota set to 26MB for card data persistence
index.html
The main HTML structure that:- Loads polyfills, SDK, configuration, and application scripts in order
- Preloads the language font to avoid render delays
- Sets up Kindle chromebar (top navigation) via messaging API
- Contains a fixed DOM structure to minimize reflows on e-ink displays
Chromebar configuration
Chromebar configuration
The chromebar is configured through the
kindle.messaging.sendMessage API:main.js (1471 lines)
The core application logic that implements:- State management: Global variables for card index, scores, review modes
- Deck operations: Create, load, save decks to localStorage
- Card management: Create cards with front/back/reading/notes/level properties
- Spaced repetition: Simplified SM-2 algorithm with difficulty levels
- Review modes: Regular, error review, starred review
- Display logic: Fixed-height elements to prevent e-ink refreshes
- Device detection: Viewport-based scaling for different Kindle models
- Statistics: Per-card view counts and review history
All functions use ES5 syntax (no arrow functions, const/let, or template literals) for compatibility with Kindle’s WebKit browser.
js/kanki_config.js
User-editable configuration file with two global objects:front: Target language textreading: Optional pronunciation (e.g., hiragana for kanji)back: Translation or definitionnotes: Additional contextlevel: Proficiency level (matches config levels)
js/sdk.js
Kindle-specific utility functions developed by Bluebotlaboratories:fetchFile(url, timeout, fixKindleFormatting): Load files via hidden iframegetDirectory(location): Parse directory listings from Kindle’s file browserflashDisplay(): Brief screen inversion for visual feedbackjoinPaths(path1, path2): Path manipulation helper
The SDK uses iframes to load local files because Kindle’s browser doesn’t support modern fetch API or AJAX for local file access.
js/polyfill.min.js
Provides ES5 polyfills for:Array.prototype.forEach,map,filter,reduceObject.keys,Object.assignString.prototype.trim,includesPromise(if needed)JSON.parse/JSON.stringify
Data persistence
KAnki stores all deck data and progress in Kindle’s localStorage at:Data structure
Data structure
The saved deck object includes:
E-ink optimizations
To minimize screen refreshes and ghosting:- Fixed heights: Card containers have predetermined pixel heights based on device
- DOM reuse: Elements are updated instead of recreated
- Visibility toggling: Elements use
display: noneinstead of removing from DOM - Scroll indicators: CSS-only indicators for scrollable content
- Device scaling: Viewport-based font scaling applied to
<html>element
Device detection
KAnki detects device resolution and applies scaling:| Device | Resolution | Scale Factor |
|---|---|---|
| Base Kindle | 600×800 | 1.0 |
| Mid-size | 750-999px width | 0.8 |
| Paperwhite 3 | 1072×1448 | 0.6 |
| High-res (Oasis, Scribe) | 1000×1400+ | 0.65 |