Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/faraasaaay/inner/llms.txt

Use this file to discover all available pages before exploring further.

Inner is distributed as a local Gradle module — the innertube directory inside the repository. There is no Maven or package-registry artifact to fetch; you clone the repository (or copy the directory) and wire the module into your build. This page covers the exact steps for both a pure Android project and a Kotlin Multiplatform project that also targets iOS.

Requirements

Android

RequirementValue
Minimum SDK26 (Android 8.0 Oreo)
Compile SDK36
JVM target21
Kotlin pluginkotlin("android") or android.kotlin.multiplatform.library

iOS

RequirementValue
TargetsiosArm64, iosSimulatorArm64, iosX64
Kotlin pluginkotlin("multiplatform")

Shared

  • Kotlin Multiplatform Gradle plugin (version compatible with your Kotlin version)
  • kotlinx.serialization plugin: org.jetbrains.kotlin.plugin.serialization
  • Android Gradle Plugin (AGP) compatible with your compileSdk = 36
  • jvmToolchain(21) configured in the kotlin {} block

Android project setup

1

Clone or copy the innertube module

Clone the Inner repository alongside your project, or copy the innertube directory directly into your project root:
# Option A — clone the full repo next to your project
git clone https://github.com/faraasaaay/inner.git

# Option B — copy only the module into your existing project root
cp -r inner/innertube ./innertube
After this step your project directory should contain an innertube/ folder with its own build.gradle.kts.
2

Include the module in settings.gradle.kts

Open your project’s settings.gradle.kts and add the module:
settings.gradle.kts
pluginManagement {
    // ... your existing plugin repositories
}

dependencyResolutionManagement {
    // ... your existing repository configuration
}

rootProject.name = "YourAppName"

include(":app")
include(":innertube") // ← add this line
3

Add the dependency in your app module

In your app module’s build.gradle.kts, declare innertube as an implementation dependency:
app/build.gradle.kts
android {
    compileSdk = 36
    defaultConfig {
        minSdk = 26
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_21
        targetCompatibility = JavaVersion.VERSION_21
    }
}

kotlin {
    jvmToolchain(21)
}

dependencies {
    implementation(project(":innertube"))
}
4

Understand the bundled dependencies

The innertube module declares all its own dependencies. When you include it you automatically get:commonMain (Android + iOS)
LibraryPurpose
ktor-client-coreMultiplatform HTTP client
ktor-client-content-negotiationContent-type negotiation plugin
ktor-client-encodingGzip/deflate content-encoding plugin
ktor-serialization-kotlinx-jsonJSON serialisation via kotlinx.serialization
androidMain only
LibraryPurpose
ktor-client-okhttpOkHttp-backed Ktor engine
brotliBrotli decompression for Android HTTP responses
newpipe-extractorStream URL extraction and cipher decoding
re2jRE2-compatible regex used during stream processing
rhinoMozilla Rhino JS engine, used to generate PoTokens
You do not need to redeclare any of these in your app module — transitive dependency resolution handles them automatically.

KMP project setup

For a Kotlin Multiplatform project targeting both Android and iOS, follow the same steps as above but reference PortableInnertube from your commonMain source set instead of the Android-only YouTube singleton.
1

Clone or copy the innertube module

Same as the Android setup — clone the repository or copy the innertube directory into your project root.
2

Include the module in settings.gradle.kts

settings.gradle.kts
include(":shared")      // your KMP shared module
include(":innertube")   // Inner's module
3

Add the dependency in your shared KMP module

shared/build.gradle.kts
kotlin {
    androidTarget {
        compilerOptions {
            jvmTarget.set(JvmTarget.JVM_21)
        }
    }

    iosArm64()
    iosSimulatorArm64()
    iosX64()

    jvmToolchain(21)

    sourceSets {
        commonMain.dependencies {
            implementation(project(":innertube"))
        }
    }
}
The innertube module’s iosMain source set automatically uses ktor-client-darwin (Apple’s URLSession-backed engine). No additional configuration is needed on your side.
4

Use PortableInnertube in commonMain

PortableInnertube is the KMP entry point available in commonMain. It accepts an optional HttpClient and exposes search, browse, home, album, artist, and playlist operations as suspend functions:
shared/src/commonMain/kotlin/MusicRepository.kt
import com.tamed.music.innertube.PortableInnertube
import com.tamed.music.innertube.models.YouTubeLocale

class MusicRepository {
    private val innertube = PortableInnertube(
        locale = YouTubeLocale(gl = "US", hl = "en-US")
    )

    suspend fun searchSongs(query: String) =
        innertube.search(query).getOrThrow().items

    suspend fun getHomeFeed() =
        innertube.home().getOrThrow()
}
For iOS-specific playback (stream URLs, PoToken resolution) you will need to add platform-specific code in iosMainPortableInnertube covers browse and search on both platforms.

Verify the setup

Once Gradle has synced successfully, confirm everything is wired correctly with a minimal smoke test that makes a live network call to the YouTube Music API — no authentication required. Android — call YouTube.visitorData(), which fetches a visitor-data token from the YouTube Music home page:
import com.tamed.music.innertube.YouTube

suspend fun verifySetup() {
    val visitorData = YouTube.visitorData().getOrNull()
    println("Visitor data: $visitorData")
    // Expected output: "Visitor data: CgtXxxxxxxxxxxx..."
}
A non-null string beginning with Cgt or Cgs confirms that the HTTP client is configured correctly and the youtubei/v1/ endpoint is reachable. KMP (commonMain / iOS) — call PortableInnertube.search() with an empty-ish query:
import com.tamed.music.innertube.PortableInnertube

suspend fun verifySetup() {
    val innertube = PortableInnertube()
    val result = innertube.search("test").getOrNull()
    println("First result: ${result?.items?.firstOrNull()?.title}")
    // Expected output: a song or video title, confirming the HTTP engine is wired correctly
}
The innertube module targets JVM 21. Make sure your project’s jvmToolchain is set to 21, or that your compileOptions / kotlinOptions allow JVM 21 bytecode. Projects configured for an older JVM target will fail to compile with an “unsupported class file major version” error at runtime or a bytecode incompatibility error at build time.

Build docs developers (and LLMs) love