KBBI is an unofficial, AI-assisted Android dictionary for Kamus Besar Bahasa Indonesia, built for fast lookup, offline-friendly reading, word study, proverbs, translations, bookmarks, and daily learning reminders.
⬇ Download KBBI 5.15.1 APK · Latest release notes
The APK is distributed through GitHub Releases. Android may ask you to allow installation from your browser or file manager. Verify that the download comes from
github.com/arrazyfathan/kbbibefore installing it.
This repository contains the Android client for KBBI. It combines a remote dictionary service with a bundled local word index, on-device Room caches, and optional AI-assisted study tools. A successful lookup is cached so previously opened content can remain available when the network is unavailable.
The app does not require an account. Bookmarks, search history, cached content, AI provider configuration, reminder preferences, language selection, and haptic preferences are stored locally on the device. AI study is generated only when requested and can use either a provider managed by the KBBI backend or an OpenAI-compatible provider configured by the user.
KBBI is an unofficial project and is not operated by or affiliated with the Indonesian government or the official KBBI publisher.
- Search Indonesian words and meanings from the home screen.
- Get suggestions from the bundled local word index before submitting a search.
- Browse and filter the complete bundled word-entry list.
- Use Android speech recognition for voice search.
- Show optional word and meaning translations in the detail screen.
- Copy or share formatted definitions through Android's share sheet.
- Turn an opened dictionary entry into a simpler explanation, natural examples, usage notes, and related words.
- Generate study content in English or Indonesian while keeping the official dictionary definitions as the primary reference.
- Use KBBI AI without entering personal provider credentials, subject to provider availability on the configured backend.
- Optionally connect directly to one or more custom OpenAI-compatible providers and choose a model for each provider.
- Test, select, edit, and remove custom provider configurations from Settings → AI word study.
- Display an AI accuracy disclaimer and identify the provider and model used for generated content.
- Cache successful word lookups in Room.
- Reopen cached meanings without a network connection.
- Cache proverb pages and proverb details for fallback when the remote service fails.
- Preserve cached meanings when a bookmark is removed.
- Store recent search history locally and clear it from Settings.
- Browse and search Indonesian proverbs with Paging 3.
- Open proverb meanings with remote-first, cache-fallback behavior.
- Save words as bookmarks and remove them with long-press actions.
- Open bookmark, word, and proverb destinations from notifications and deep links.
- Search selected text through Android's
ACTION_PROCESS_TEXTmenu. - Receive shared
text/plaincontent from other apps. - Handle
kbbi://word/{word},kbbi://proverb/{slug}, andkbbi://bookmarkslinks. - Provide launcher shortcuts for search, bookmarks, proverbs, and a random word.
- Schedule daily word, daily proverb, and bookmark-review reminders with WorkManager.
- Request microphone and notification permissions only when their related feature is used.
- Choose English or Indonesian as the application language.
- Choose a KBBI-managed AI provider and model, or configure custom OpenAI-compatible providers.
- Configure reminder types and delivery times independently.
- Enable or disable semantic haptic feedback across the application.
- Check GitHub Releases for app updates and download a newer APK.
- View privacy policy, terms and conditions, and open-source licenses in the app.
- Use Material 3, edge-to-edge layouts, animated transitions, and Lottie states.
preview.mp4
KBBI is a multi-module Android project organized by feature and layer. Dependencies point inward toward domain contracts:
:app
├── application startup and Koin assembly
├── Navigation3 root graph and external-intent routing
├── notification permission and WorkManager adapters
└── application-wide UI coordination
:feature:<name>:presentation
├── feature domain contracts
├── :core:domain
├── :core:presentation:ui
└── :core:presentation:designsystem
:feature:<name>:data
├── feature domain contracts
├── :core:data
├── :core:domain
└── :core:logging
:feature:<name>:domain
└── domain models, repository interfaces, and use cases
:core:observability
├── Firebase Analytics, Crashlytics, and Performance Monitoring adapters
├── privacy-aware reporting preferences and collection gates
└── sanitized network performance traces and diagnostic context
Presentation follows an MVI-style unidirectional flow with immutable screen state, user actions, ViewModels, and one-shot events. Koin assembles implementations at the application boundary.
The included build-logic build provides kbbi.android.application and kbbi.android.library convention plugins. Apply the matching plugin in each Android module's plugins block to share the compile SDK (37), minimum SDK (24), Java compatibility (17), and Android instrumentation runner. Keep module namespaces, application IDs, flavors, Compose features, and other module-specific settings in that module's build file. Dependency and plugin versions remain in gradle/libs.versions.toml.
.
├── build-logic/ # Shared Android application and library conventions
├── app/
│ ├── di/ # App-level use-case and ViewModel registration
│ ├── intent/ # External text, sharing, and deep-link parsing
│ ├── navigation/ # Navigation3 graph, routes, and shortcuts
│ ├── notifications/ # WorkManager scheduler, worker, permission gateway
│ └── ui/ # Application-wide UI state
├── core/
│ ├── app-update/ # GitHub release checks and update prompt
│ ├── data/ # Shared Ktor client and safe API calls
│ ├── di/ # Shared Koin modules
│ ├── domain/ # AppResult, DataError, shared primitives
│ ├── logging/ # Application and network logging
│ ├── observability/ # Crash, analytics, and performance reporting
│ ├── presentation/
│ │ ├── designsystem/ # Theme, typography, resources, haptics, components
│ │ └── ui/ # UiText, alerts, errors, loading coordination
│ └── utils/ # System-bar and voice-recognition helpers
├── feature/
│ ├── bookmark/presentation/ # Saved-word UI and deletion flow
│ ├── detail/presentation/ # Meanings, translation, study-card state, copy/share, bookmarks
│ ├── home/
│ │ ├── data/ # Word DB, remote APIs, bundled catalog
│ │ ├── domain/ # Word/search/bookmark/translation contracts
│ │ └── presentation/ # Search, suggestions, history, voice input
│ ├── proverb/
│ │ ├── data/ # Paging, remote source, Room cache
│ │ ├── domain/ # Proverb contracts and use cases
│ │ └── presentation/ # Proverb list, search, and meaning UI
│ ├── settings/
│ │ ├── data/ # DataStore preference implementations
│ │ ├── domain/ # Reminder and UI preference contracts
│ │ └── presentation/ # Settings, language, legal documents
│ ├── wordstudy/
│ │ ├── domain/ # AI provider/configuration and word-study contracts/use cases
│ │ ├── data/ # Backend/custom AI sources, encrypted configuration, DTOs
│ │ └── presentation/ # AI provider settings screen and ViewModel
│ ├── splash/presentation/ # Animated startup screen
│ └── words/presentation/ # Searchable local word list
├── .github/workflows/ # Validation and tagged release pipeline
├── fastlane/ # Local automation
└── gradle/libs.versions.toml # Dependency and plugin versions
- The query is normalized and validated by the domain use case.
- Local suggestions come from
feature/home/data/src/main/assets/entries.json. WordRepositorycheckskbbi_dbfor a cached entry.- Cached data is returned immediately when available.
- A cache miss requests the configured dictionary API.
- A successful response is persisted in Room.
- Bookmarking changes the stored entry's
isSavedflag; removing a bookmark keeps its cached meaning.
The bundled asset contains word entries, not full definitions. A word must be opened successfully at least once before its meaning is available offline.
ProverbViewModeldebounces the search query.- Paging loads matching pages from the remote API.
- Successful pages are cached in
proverb_db. - Cached pages are used when a remote page fails.
- Proverb details are remote-first and cached by slug for later fallback.
- The detail screen maps its displayed Home word model to the Word Study source model, which builds a bounded request from the headword, word classes, definitions, and selected output language.
- In KBBI AI mode, the app loads the backend provider catalog and sends generation requests through the configured KBBI API.
- In Custom Provider mode, the app sends the same study request directly to the selected OpenAI-compatible
/chat/completionsendpoint. - The response is validated before its explanation, examples, usage notes, and related words are shown alongside an AI disclaimer.
- Custom mode never silently falls back to KBBI AI when its provider is unavailable or misconfigured.
Custom provider API keys are encrypted with Android Keystore. Provider configuration is kept in app-local DataStore and excluded from Android cloud backup and device-to-device transfer. Custom provider requests, credentials, and provider details are excluded from app logging, analytics, and performance reporting. Users remain responsible for their selected provider's credentials, costs, terms, and data practices.
- DataStore persists reminder, haptic, and AI provider configuration.
- WorkManager schedules unique periodic work for each enabled reminder type.
- Notification taps route back into the appropriate word, proverb, or bookmark destination.
- App language is stored through AndroidX per-app locale APIs.
The app uses the :core:observability module to provide opt-in usage and performance diagnostics, plus crash diagnostics:
- Firebase Crashlytics records crashes, selected non-fatal failures, warning/error breadcrumbs, and allowlisted diagnostic keys. Crash reporting is enabled by default.
- Firebase Analytics records anonymous screen views and feature events when Usage analytics is enabled. It is disabled by default.
- Firebase Performance records app performance data and sanitized HTTP timing metrics when Performance diagnostics is enabled. It is disabled by default and only eligible for production release builds.
- Search terms, dictionary definitions, translations, generated AI study content, custom provider details, and the dictionary visitor identifier are not sent to Firebase. Network performance URLs redact word, translation, and proverb identifiers; backend AI traces contain no study content, and custom-provider requests are not reported.
- Reporting choices are stored locally and can be changed independently under Settings → Privacy & diagnostics. Disabling crash reporting also deletes unsent Crashlytics reports; changes take effect fully after restarting the app.
Firebase reporting requires the application's Firebase configuration. The implementation uses no-op reporters when a reporting channel is disabled, keeping feature code independent of the telemetry provider.
| Area | Technology |
|---|---|
| Language | Kotlin 2.4.20, Java 17 target |
| Build | Gradle 9.7.1, Android Gradle Plugin 9.4.1, KSP |
| Android | Minimum SDK 24, target/compile SDK 37 |
| UI | Jetpack Compose BOM 2026.09.00, Material 3, Lottie |
| Navigation | AndroidX Navigation3 |
| State | ViewModel, StateFlow, coroutines, channel-backed events |
| Networking | Ktor Client 3.6.0 with OkHttp and kotlinx.serialization |
| Persistence | Room 2.8.5, Preferences DataStore 1.2.1 |
| Background work | WorkManager 2.12.0 |
| Dependency injection | Koin 4.2.2 |
| Lists | Paging 3.5.1 |
| Quality | Android Lint, Detekt, Ktlint, Kover |
| Automation | GitHub Actions, Fastlane, Renovate |
Dependency versions are centralized in gradle/libs.versions.toml.
- Android Studio with Android SDK 37 installed
- JDK 17
- Git
- Access to a compatible KBBI API base URL
- Android device or emulator running API 24 or newer
git clone https://github.com/arrazyfathan/kbbi.git
cd kbbiCreate local.properties and provide both the Android SDK path and API URL:
sdk.dir=/absolute/path/to/Android/sdk
KBBI_BASE_URL=https://your-compatible-api.example/KBBI_BASE_URL may instead be passed as a Gradle property or environment variable:
./gradlew -PKBBI_BASE_URL=https://your-compatible-api.example/ helpThe build fails early when no API URL is configured. Keep private endpoints and credentials out of version control.
For KBBI AI, the configured backend is expected to expose GET /api/v1/ai/providers and POST /api/v1/ai/word-study. A custom OpenAI-compatible provider can instead be configured at runtime under Settings → AI word study; no custom-provider API key is required at build time or should be added to project files.
./gradlew assembleDevelopmentDebug
./gradlew installDevelopmentDebugIn Android Studio, select the developmentDebug build variant and run the app configuration.
Development builds can be distributed to Firebase App Distribution by pushing a tag whose name exactly matches the development versionName, including the -dev suffix. For example:
git tag 5.21.5-dev
git push origin 5.21.5-devThe workflow validates tests, lint, and the developmentDebug APK before uploading it with appDistributionUploadDevelopmentDebug. Branch pushes and pull requests remain validation-only. Production tags continue to publish the signed production APK as a GitHub Release.
The configured tester is listed in app/firebase/testers.txt. CI generates app/firebase/release-notes.txt from commits since the nearest preceding reachable tag before uploading; the tracked file documents the canonical input path.
Tagged development distribution requires the FIREBASE_APP_DISTRIBUTION_SERVICE_ACCOUNT_JSON GitHub Actions secret containing the complete Google service-account JSON. Grant the service account the Firebase App Distribution Admin role, store the key only in GitHub Actions secrets, and follow Firebase's service-account authentication guidance. The upload is configured through Firebase's official Gradle plugin.
The stage flavor dimension defines:
| Variant | Application ID | App label |
|---|---|---|
development |
com.arrazyfathan.kbbi.dev |
Dev KBBI |
production |
com.arrazyfathan.kbbi |
KBBI |
Common tasks:
./gradlew assembleDevelopmentDebug
./gradlew assembleProductionDebugVersion components come from app/version.properties. Release APK names are generated as:
- Production:
kbbi-v<version>-release.apk - Other flavors:
kbbi-<flavor>-v<version>-release.apk
Run the same validation used by CI:
./gradlew testDevelopmentDebugUnitTest lintDevelopmentDebug assembleDevelopmentDebug --stacktraceAdditional checks:
./gradlew detekt
./gradlew ktlintCheckRun connected Android tests on an emulator or device:
./gradlew connectedDevelopmentDebugAndroidTestGenerate Kover coverage for the application variant:
./gradlew :app:koverLogDevelopmentDebug
./gradlew :app:koverHtmlReportDevelopmentDebugThe HTML report is written under app/build/reports/kover/.
Tests cover domain use cases, remote and local data behavior, AI request contracts and provider configuration, mapping, app updates, external intents, shortcuts, ViewModels, settings, Room, legal screens, and design-system components.
| Permission | Purpose |
|---|---|
| Internet/network state | Dictionary, translation, proverb, AI study, and release requests |
| Microphone | Voice search; requested when voice search is used |
| Notifications | Daily reminders; requested when a reminder is enabled on Android 13+ |
Haptic feedback uses Android's semantic Compose haptic API and does not require the VIBRATE permission.
Production release packaging is blocked unless all signing values are supplied as Gradle properties or environment variables:
ANDROID_KEYSTORE_PATH
ANDROID_KEYSTORE_PASSWORD
ANDROID_KEY_ALIAS
ANDROID_KEY_PASSWORD
Example:
export ANDROID_KEYSTORE_PATH=/absolute/path/to/release.keystore
export ANDROID_KEYSTORE_PASSWORD=your-store-password
export ANDROID_KEY_ALIAS=your-key-alias
export ANDROID_KEY_PASSWORD=your-key-password
./gradlew assembleProductionReleaseThe workflow in .github/workflows/android.yml performs the following:
- Pull requests and pushes to
main: unit tests, Android lint, and a development debug APK. - Version tags: signed production APK build, artifact upload, generated commit notes, and GitHub Release publication.
Release secrets:
KBBI_BASE_URLANDROID_KEYSTORE_BASE64ANDROID_KEYSTORE_PASSWORDANDROID_KEY_ALIASANDROID_KEY_PASSWORD
Fastlane currently provides bundle exec fastlane android test, which delegates to Gradle tests.
- Future development roadmap
- Architecture evolution notes
- Fastlane configuration
- GitHub releases
- Issue tracker
Designed and developed by 2022 arrazyfathan (Ar Razy Fathan Rabbani)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.