Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

246 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Supabase KMP Logo

Kotlin Ktor Platforms Maven Central License

Supabase KMP

Kotlin Multiplatform SDK for Supabase β€” type-safe, coroutine-first, modular client for every platform Kotlin runs on.

Full guides for Authentication, Database, Storage, Realtime and Edge Functions live on the docs site. This README is the quick start.

Features

  • Type-safe Result monad β€” SupabaseResult<T> with map, flatMap, recover β€” no exceptions leak to callers
  • Value class IDs β€” UserId, BucketId, SessionId, ChannelId prevent mixups at compile time
  • Typed filter DSL β€” Column<T> tokens with infix operators (eq, neq, greater, like, ilike, inList, isNull, textSearch, contains, …); the compiler rejects type mismatches
  • OAuth (17 providers) + MFA β€” TOTP and phone-based multi-factor auth with CSPRNG-backed PKCE
  • Native passkeys β€” cross-platform WebAuthn ceremony (Android, iOS, macOS, JVM, Wasm) behind a pluggable authenticator, or bring your own
  • Session management β€” Single-flight auto-refresh, pluggable persistence (SessionStorage), SessionState via StateFlow
  • Realtime WebSocket β€” Phoenix protocol with auto-reconnection, exponential backoff, presence, offline send buffering, binary broadcast (raw ByteArray)
  • Secure by default β€” Credential headers redacted from logs, smart retries (429/5xx + Retry-After)
  • End-to-end encryption β€” Optional supabase-e2ee: derive a shared AES-256-GCM key on-device (ECDH β†’ HKDF) so Supabase only ever stores ciphertext. Includes a KeyDirectory (publish/fetch public keys), out-of-band safetyNumber() verification (MITM protection), and EncryptedRoom β€” a verify-first encrypt-on-send / decrypt-on-receive chat room over supabase-realtime
  • 16 platform targets β€” Android, iOS, macOS, tvOS, watchOS, JVM, Linux, Windows, and WasmJs

Setup

Requirements: the published Android/JVM artifacts are compiled for Java 17 and ship inline functions, so consuming modules must build with a jvmTarget of 17 or higher (Android compileOptions/kotlinOptions JVM 17+, or JVM jvmToolchain(17) or newer β€” Java 21 is fine). Only a lower target fails, with "cannot inline bytecode built with JVM target 17 into bytecode being built with JVM target 11"; matching or higher targets inline cleanly.

Add the modules you need to your version catalog:

[versions]
supabase-kmp = "1.0.0"

[libraries]
supabase-client = { module = "io.github.androidpoet:supabase-client", version.ref = "supabase-kmp" }
supabase-auth = { module = "io.github.androidpoet:supabase-auth", version.ref = "supabase-kmp" }
supabase-database = { module = "io.github.androidpoet:supabase-database", version.ref = "supabase-kmp" }
supabase-storage = { module = "io.github.androidpoet:supabase-storage", version.ref = "supabase-kmp" }
supabase-realtime = { module = "io.github.androidpoet:supabase-realtime", version.ref = "supabase-kmp" }
supabase-functions = { module = "io.github.androidpoet:supabase-functions", version.ref = "supabase-kmp" }
supabase-sync = { module = "io.github.androidpoet:supabase-sync", version.ref = "supabase-kmp" } # + supabase-sync-core, supabase-sync-sqldelight for offline-first sync

# Optional add-ons β€” only add the ones you need
supabase-auth-google = { module = "io.github.androidpoet:supabase-auth-google", version.ref = "supabase-kmp" }
supabase-auth-apple = { module = "io.github.androidpoet:supabase-auth-apple", version.ref = "supabase-kmp" }
supabase-auth-passkey = { module = "io.github.androidpoet:supabase-auth-passkey", version.ref = "supabase-kmp" }
supabase-auth-admin = { module = "io.github.androidpoet:supabase-auth-admin", version.ref = "supabase-kmp" }
supabase-e2ee = { module = "io.github.androidpoet:supabase-e2ee", version.ref = "supabase-kmp" }
kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation(libs.supabase.client)
            implementation(libs.supabase.auth)
            implementation(libs.supabase.database)
            implementation(libs.supabase.storage)
            implementation(libs.supabase.realtime)
            implementation(libs.supabase.functions)
        }
    }
}

Only depend on what you use β€” each module is published independently. Optional add-ons: supabase-auth-google, supabase-auth-apple, supabase-auth-passkey (native sign-in), supabase-auth-admin (service-role; server-side only) and supabase-e2ee (client-side end-to-end encryption).

Quick start

Everything starts from a SupabaseClient. Create one, then build the feature clients you need from it.

val client = Supabase.create(
    projectUrl = "https://your-project.supabase.co",
    apiKey = "your-anon-key",
) {
    logging = true
}

val auth = createAuthClient(client)
val database = createDatabaseClient(client)
val storage = createStorageClient(client)
val realtime = createRealtimeClient(client)
val functions = createFunctionsClient(client)

Use the anon key in client apps β€” never the service-role key.

Results, not exceptions

Every fallible call returns a SupabaseResult<T> β€” a sealed Success/Failure type. There are no exceptions to catch on the happy path; you branch with onSuccess/onFailure and transform with map/flatMap/recover.

@Serializable
data class Todo(val id: String, val title: String, val done: Boolean)

// Typed column tokens β€” hand-written here, or emitted by codegen.
object Todos {
    val done = Column<Boolean>("done")
    val createdAt = Column<String>("created_at")
}

database.selectTyped<Todo>(table = "todos") {
    where { Todos.done eq false }
    orderBy(Todos.createdAt, Order.DESC)
    limit(25)
}.onSuccess { todos ->
    println("Got ${todos.size} todos")
}.onFailure { error ->
    println("Error: ${error.message}")
}

Errors carry a category (CONFLICT, NOT_FOUND, UNAUTHORIZED, RATE_LIMITED, VALIDATION, Internal, NETWORK, UNKNOWN) so you can branch without parsing codes β€” plus chainable helpers like onUnauthorized { }, onRateLimited { } and onNetworkError { }. See Results & Errors for the full surface.

Modules

Module Artifact Description
supabase-core io.github.androidpoet:supabase-core Result monad, error types, value class IDs, filter DSL
supabase-client io.github.androidpoet:supabase-client HTTP transport, platform engines, auth state, factory wiring
supabase-auth io.github.androidpoet:supabase-auth Email, phone, OTP, OAuth (17 providers), MFA, PKCE, session management, passkeys
supabase-auth-google io.github.androidpoet:supabase-auth-google Native Google sign-in (Android Credential Manager)
supabase-auth-apple io.github.androidpoet:supabase-auth-apple Native Sign in with Apple (AuthenticationServices)
supabase-auth-passkey io.github.androidpoet:supabase-auth-passkey Passkey/WebAuthn ceremony driver β€” native on Android, iOS, macOS, JVM & Wasm (or bring your own)
supabase-auth-admin io.github.androidpoet:supabase-auth-admin Service-role admin APIs (server-side only)
supabase-database io.github.androidpoet:supabase-database PostgREST CRUD, RPC, typed filter extensions
supabase-storage io.github.androidpoet:supabase-storage Bucket CRUD, file upload/download, signed & public URLs
supabase-realtime io.github.androidpoet:supabase-realtime WebSocket (Phoenix protocol), auto-reconnect, broadcast, presence
supabase-functions io.github.androidpoet:supabase-functions Edge function invocation with typed responses
supabase-e2ee io.github.androidpoet:supabase-e2ee Optional client-side E2E encryption (ECDH β†’ HKDF β†’ AES-256-GCM) + key directory, safety-number verification & EncryptedRoom over realtime
supabase-sync-core io.github.androidpoet:supabase-sync-core Offline-first sync engine β€” pull/merge/push, conflict resolution, keyset cursor (transport-agnostic)
supabase-sync-sqldelight io.github.androidpoet:supabase-sync-sqldelight On-device local store over SQLDelight β€” typed-table SSOT, outbox, cursor, pagination
supabase-sync io.github.androidpoet:supabase-sync Supabase remote source β€” incremental pull/push over PostgREST + live Realtime deltas

Targets

Android Β· JVM Β· iOS Β· macOS Β· tvOS Β· watchOS Β· Linux Β· Windows Β· WasmJs β€” 16 targets in total, on OkHttp (Android/JVM), Darwin (Apple), CIO (Linux/Windows) and the JS Ktor engine for the browser (wasmJs). The browser target ships only as Kotlin/Wasm via wasmJs β€” there is no separate Kotlin/JS (js()) artifact.

Documentation

Build

./gradlew compileKotlinJvm                 # compile a single target
./gradlew jvmTest                          # run JVM unit tests
./gradlew build --no-configuration-cache   # full build (all platforms)

Quality gates run in CI on every PR β€” run them locally before pushing:

./gradlew detekt                    # static analysis (config/detekt/detekt.yml)
./gradlew apiCheck                  # fails on unintended public/binary API changes
./gradlew jvmTest koverHtmlReport   # tests + coverage report

If you intentionally change the public API, regenerate the dumps with ./gradlew apiDump and commit them. See CONTRIBUTING.md for the full workflow.

Contributing

Contributions are welcome! If you've found a bug, have an idea for an improvement, or want to contribute new features, please open an issue or submit a pull request.

Find this repository useful? ❀️

Support it by joining stargazers for this repository. ⭐
Also, follow me on GitHub for my next creations! 🀩

License

MIT Β© 2026 Ranbir Singh

About

A Kotlin Multiplatform (KMP) SDK for Supabase, enabling seamless integration across Android, iOS, and other platforms.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

47 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages