A Kotlin SDK for integrating with the YouVersion Platform, enabling developers to display Scripture content and implement user authentication in any Android environment. Multiplatform support is currently not available.
- Features
- Requirements
- Installation
- Getting Started
- Usage
- Sample App
- For Different Use Cases
- Development Setup
- Contributing
- Documentation
- Support
- License
- 📖 Scripture Display - Easy-to-use Jetpack Compose components for displaying Bible verses, chapters, and passages with
BibleText - 📕 Bible Reader - A complete Bible reading experience inside your app with
BibleReader - 🖍️ Highlights - The signed-in user's YouVersion highlights are rendered in
BibleTextand can be created, recolored, and removed from the reader - 🔐 User Authentication - Seamless "Sign In with YouVersion" integration using
SignInWithYouVersionButton, with a top-level toggle to disable all sign-in UI - 🌅 Verse of the Day - Built-in
VerseOfTheDaycomponent and API access to VOTD data - 🚀 Modern Kotlin - Built with coroutines, Jetpack Compose, and Material Theming
- 💾 Smart Caching - Automatic local caching for improved performance
- Android 6.0+ (API 23)
- Android Studio Narwhal+
- Kotlin 2.2.0+
- A YouVersion Platform API key (Register here)
Be sure you have mavenCentral() in your repositories block.
// settings.gradle.kts
repositories {
google()
mavenCentral()
}The Platform SDK is broken into three main modules:
platform-core: Provides the core functionality for accessing the YouVersion Platform API.platform-ui: Provides UI components for displaying Bible content.platform-reader: Provides a full Bible Reader experience.
I want to only access the Bible API's and build my own integrations
You will only need platform-core.
I want to display Bible content or authenticate with YouVersion in my app but with my own styling
You will need platform-ui and platform-core.
I want a full, batteries included, drop-in Bible Reader experience
You will need platform-reader, platform-ui, and platform-core.
Great! Now that you know which modules you need, you can proceed with installation.
# gradle/libs.versions.toml
[versions]
youVersionPlatform = "1.8.3"
[libraries]
youversion-platform-core = { module = "com.youversion.platform:platform-core", version.ref = "youVersionPlatform" }
youversion-platform-ui = { module = "com.youversion.platform:platform-ui", version.ref = "youVersionPlatform" }
youversion-platform-reader = { module = "com.youversion.platform:platform-reader", version.ref = "youVersionPlatform" }// app/build.gradle.kts
implementation(libs.youversion.platform.core)
implementation(libs.youversion.platform.ui)
implementation(libs.youversion.platform.reader)val youVersionPlatform = "1.8.3"
implementation("com.youversion.platform:platform-core:$youVersionPlatform")
implementation("com.youversion.platform:platform-ui:$youVersionPlatform")
implementation("com.youversion.platform:platform-reader:$youVersionPlatform")- Get Your API Key: Register your app with YouVersion Platform to acquire an app key
- Configure the SDK: Add the following to your app's initialization:
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
YouVersionPlatformConfiguration.configure(
context = this,
appKey = TODO("YOUR_APP_KEY_HERE"),
)
}
}Display a single verse:
@Composable
fun Demo() {
BibleText(
reference = BibleReference(versionId = 3034, bookUSFM = "JHN", chapter = 3, verse = 16)
)
}Display a verse range:
@Composable
fun Demo() {
BibleText(
reference = BibleReference(versionId = 3034, bookUSFM = "JHN", chapter = 3, verseStart = 16, verseEnd = 20)
)
}Or display a full chapter:
@Composable
fun Demo() {
BibleText(
reference = BibleReference(versionId = 3034, bookUSFM = "JHN", chapter = 3)
)
}Note: For longer passages, wrap
BibleTextin averticalScroll. The SDK automatically fetches Scripture from YouVersion servers and maintains a local cache for improved performance.
When the user is signed in and has granted the highlights permission, BibleText also renders their YouVersion highlights behind the verse text. See Highlights.
Displays a full Bible reading experience, very similar to the YouVersion Bible app, ready to be added as a tab in your app.
@Composable
fun ReaderTab() {
BibleReader()
}The sign-in prompt the reader presents to a signed-out user names your app and shows your own reason for asking. Both come from configuration:
YouVersionPlatformConfiguration.configure(
context = this,
appKey = "YOUR_APP_KEY_HERE",
appName = "Your App Name",
signInPromptMessage = "Sign in to see your **YouVersion** highlights in **Your App Name**",
)signInPromptMessage is optional and supports **bold** markdown. appName is optional too — leave it out and the prompt names your app by its launcher label — but set it when that label is not the name you want a reader to see before granting account access.
To open to a specific passage:
BibleReader(
bibleReference = BibleReference(versionId = 3034, bookUSFM = "PSA", chapter = 23),
)To offer your own fonts in the reader's font settings sheet, or to render a bottom bar beneath the reader, pass fontDefinitionProvider and bottomBar.
By default, a signed-out user who taps a verse is prompted to sign in with YouVersion. To suppress all sign-in UI, including that prompt and the header menu's sign-in option, set isSignInEnabled to false during configuration:
YouVersionPlatformConfiguration.configure(
context = this,
appKey = "YOUR_APP_KEY_HERE",
isSignInEnabled = false,
)When sign-in is disabled, the reader hides the highlight colors from a signed-out user rather than offering a control that could never work. A user who is already signed in keeps their highlight colors, since they need nothing further.
By default, the version picker offers Bible versions in every available language. To restrict it to a specific set of languages, pass permittedLanguageTags during configuration. For example, to make only English versions available:
YouVersionPlatformConfiguration.configure(
context = this,
appKey = "YOUR_APP_KEY_HERE",
permittedLanguageTags = setOf("en"),
)Tags follow BCP 47 (e.g. "en" for English, "es" for Spanish). When the resulting list contains versions in only one language, the language button in the version picker is hidden automatically.
To restrict the version picker to a specific set of Bible versions, pass permittedVersionIds during configuration:
YouVersionPlatformConfiguration.configure(
context = this,
appKey = "YOUR_APP_KEY_HERE",
permittedVersionIds = setOf(12, 111, 1588),
)IDs are the YouVersion Bible version IDs (e.g. 111 for NIV, 1588 for AMP). Combines with permittedLanguageTags — a version must satisfy both filters to be shown.
Use the built-in VOTD component:
@Composable
fun Demo() {
CompactVerseOfTheDay()
// Or
VerseOfTheDay()
}Or fetch VOTD data for custom UI:
suspend fun fetchVotd(): YouVersionVerseOfTheDay {
val dayOfTheYear = Calendar.getInstance().get(Calendar.DAY_OF_YEAR)
return YouVersionApi.votd.verseOfTheDay(dayOfTheYear)
}Integrating "Sign In with YouVersion" is straightforward. The SDK handles the entire authentication flow, including launching the sign-in screen, handling the redirect, and managing tokens.
To handle the redirect from the YouVersion authentication, you need to add an intent filter to your main activity in your AndroidManifest.xml file. The SDK will use this to receive the authentication result.
<!-- AndroidManifest.xml -->
<activity
android:name=".MainActivity"
android:exported="true">
<!-- ... existing intent filters -->
<!-- Handle OAuth callback -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="youversionauth"
android:host="callback" />
</intent-filter>
</activity>Your main activity must extend SignInWithYouVersionActivity. This allows the SDK to automatically handle the result from the sign-in process.
// MainActivity.kt
import com.youversion.platform.ui.signin.SignInWithYouVersionActivity
class MainActivity : SignInWithYouVersionActivity() {
// ...
}Use the SignInWithYouVersionButton composable in your UI. You can use the SignInViewModel to check if the user is already signed in and conditionally display the button.
SignInWithYouVersionPermission.PROFILE: To access the user's name and profile picture.SignInWithYouVersionPermission.EMAIL: To access the user's email address.SignInWithYouVersionPermission.HIGHLIGHTS: To read and write the user's Bible highlights. See Highlights.
// ProfileScreen.kt
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.youversion.platform.core.users.model.SignInWithYouVersionPermission
import com.youversion.platform.ui.signin.SignInViewModel
import com.youversion.platform.ui.views.SignInWithYouVersionButton
@Composable
fun ProfileScreen() {
val signInViewModel = viewModel<SignInViewModel>()
val state by signInViewModel.state.collectAsStateWithLifecycle()
if (state.isSignedIn) {
Column {
Text("Welcome, ${state.userName ?: "User"}!")
Text("Your email is ${state.userEmail ?: "not available"}.")
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { signInViewModel.onAction(SignInViewModel.Action.SignOut()) }) {
Text("Sign Out")
}
}
} else {
SignInWithYouVersionButton(
permissions = {
setOf(
SignInWithYouVersionPermission.PROFILE,
SignInWithYouVersionPermission.EMAIL
)
}
)
}
}The SignInViewModel automatically updates its state when authentication completes, and your UI will recompose to reflect the user's authentication status.
Highlights belong to the user's YouVersion account, so a highlight created in your app appears in the YouVersion Bible app and in any other app the user has granted access to.
BibleReader provides the full experience with no extra work: tapping a verse opens the verse action sheet with a color picker, choosing a color highlights the selected verses, and choosing the color a verse already has removes the highlight. On dark reader themes the colors are dimmed automatically so the verse text stays readable. BibleText renders the same highlights, so a custom reading UI built on platform-ui stays in sync with the reader.
Reading and writing highlights requires the user to be signed in and to have granted SignInWithYouVersionPermission.HIGHLIGHTS. BibleReader asks for it at the moment it is needed, taking one of two routes:
- A signed-out user is offered sign-in, with the highlights permission included in the requested permissions. The grant rides along with the sign-in.
- A signed-in user who has not granted it yet is shown a confirmation dialog and then the YouVersion permission page. This is the data exchange flow, and it exists so the user does not have to sign in again just to grant one more permission.
Both routes return through the same youversionauth://callback deep link used by sign-in, so highlights only work end to end once your app has completed the Authentication setup — the manifest intent filter and a main activity extending SignInWithYouVersionActivity. Without that setup the grant never reaches the SDK and highlights stay unavailable.
To check whether the permission has been granted:
val hasHighlightsPermission = YouVersionApi.hasPermission(SignInWithYouVersionPermission.HIGHLIGHTS)Apps that need to start the same permission flow themselves can do it from Compose with rememberDataExchange:
import com.youversion.platform.core.users.model.SignInWithYouVersionPermission
import com.youversion.platform.ui.dataexchange.rememberDataExchange
@Composable
fun AllowHighlightsButton() {
val requestDataExchange = rememberDataExchange()
val coroutineScope = rememberCoroutineScope()
Button(
onClick = {
coroutineScope.launch {
val result = requestDataExchange(setOf(SignInWithYouVersionPermission.HIGHLIGHTS))
if (result?.grants(SignInWithYouVersionPermission.HIGHLIGHTS) == true) {
// The grant is already persisted; highlights load on the next read.
}
}
}
) {
Text("Allow highlights")
}
}Outside Compose, use DataExchangeHandler(activityResultRegistry).requestDataExchange(...) directly. Either way the granted permission is persisted for you before the call returns, so a later YouVersionApi.hasPermission(...) reflects it without any extra work.
Note: Data exchange only works for a user who is already signed in — it mints its token from the existing access token. For a signed-out user nothing is presented at all (the result is
DataExchangeStatus.NotStarted); requestSignInWithYouVersionPermission.HIGHLIGHTSas part of sign-in instead.rememberDataExchangeandDataExchangeHandlerlive inplatform-ui.
Apps using only platform-core can read and write highlights directly through YouVersionApi.highlights. All four calls are suspend functions and require the signed-in user to have granted the highlights permission.
// Read a chapter's highlights
val highlights = YouVersionApi.highlights.highlights(versionId = 111, passageId = "JHN.3")
// Create, recolor, and remove a highlight on a single verse
YouVersionApi.highlights.createHighlight(versionId = 111, passageId = "JHN.3.16", color = "fffe00")
YouVersionApi.highlights.updateHighlight(versionId = 111, passageId = "JHN.3.16", color = "5dff79")
YouVersionApi.highlights.deleteHighlight(versionId = 111, passageId = "JHN.3.16")Colors are hex strings without a leading #. The palette the reader offers is fffe00 (yellow), 5dff79 (green), 00d6ff (cyan), ffc66f (orange), and ff95ef (pink), matching the Swift SDK.
All four calls throw YouVersionNetworkException with reason NOT_PERMITTED when the user has not granted highlights access; that request will not succeed on retry. The read call also throws MISSING_AUTHENTICATION when the request was unauthenticated, which a sign-in or token refresh may resolve. The create, update, and delete calls report an unauthenticated request as a false return instead of throwing, so check their Boolean result too — false means the write did not happen.
Explore the examples directory for a complete sample app demonstrating:
- Scripture display with various reference types
- The full
BibleReaderexperience, including highlights - User authentication flows
- VOTD integration
- Best practices for token storage
To run the sample app:
- Open the
platform-sdk-kotlindirectory in Android Studio - Wait for Gradle sync to complete (File → Sync Project with Gradle Files if needed)
- Add your API key to
examples/sample-android/src/main/java/com/youversion/platform/MainApplication.kt - Select
sample-androidfrom the run configuration dropdown - Create an emulator if needed (Tools → Device Manager → Create Device)
- Click Run
Building an Android application? This Kotlin SDK provides native Jetpack Compose components including BibleText, BibleReader, VerseOfTheDay, and SignInWithYouVersionButton using modern language features.
Need direct access to YouVersion Platform APIs? See our comprehensive API documentation for advanced integration patterns and REST endpoints.
Building AI applications with Bible content? Access YouVersion's LLM-optimized endpoints and structured data designed for language models. See our LLM documentation for details.
After cloning the repo, install Node.js dependencies to enable git hooks (commit message linting):
npm installThis installs husky and commitlint, which enforce Conventional Commits on every commit. Without this step, commits with non-conforming messages will pass locally but fail in CI.
User-facing strings in platform-ui and platform-reader must come from synced string resources (platform-localization), not hardcoded Kotlin literals.
# Fail on hardcoded UI strings in platform-ui and platform-reader
./gradlew verifyNoHardcodedUiStrings
# Root check also runs the guardrail task
./gradlew checkGreptile PR rules live in .greptile/. See docs/localization-guardrails.md for the full policy.
See CONTRIBUTING.md for details on how to get started.
- API Documentation - Complete API reference
- LLM Integration Guide - AI/ML integration docs
- Release Process - Contribution and release guidelines
- Release Runbook - Recovery procedures when a release fails partway
- Sample Code - Working examples and best practices
- Issues: GitHub Issues
- Questions: Open a discussion
- Platform Support: YouVersion Platform
This SDK is licensed under the Apache License 2.0. See LICENSE for details.
Made with ❤️ by YouVersion
