
Enables seamless authentication with Google, Apple, and Github using Firebase. Facilitates integration through customizable sign-in buttons and provides comprehensive multiplatform support for mobile applications.
Simple and easy-to-use authentication for Compose Multiplatform apps on
Android, iOS, Desktop (JVM) and Web (JS + wasm). Sign in with Google,
Apple, Facebook, GitHub, Microsoft, email/password, magic links, phone
number or anonymously — backed by Firebase or Supabase (or your
own backend), with every API callable from commonMain on every target.
Every sign-in method is served by a backend (or by your own server, when the method just hands you a token). So two questions: which backend runs on your platforms, and which methods that backend serves.
| Backend | Android | iOS | Desktop (JVM) | Web (JS) | Web (wasm) |
|---|---|---|---|---|---|
| Firebase | ✅ | ✅ | ✅ (REST) | ✅ | ✅ (REST²) |
| Supabase | ✅ | ✅ | ✅ | ✅ | ✅ |
("your server" below = no backend needed — the state hands you the provider's token to verify yourself.)
| Sign-in method | Works with | Android | iOS | Desktop (JVM) | Web (JS) | Web (wasm) |
|---|---|---|---|---|---|---|
| your server · Firebase · Supabase | ✅ | ✅ | ✅ | ✅ | ✅ | |
| Apple | Firebase · Supabase | ✅ | ✅ native | ✅ | ✅⁴ | ✅⁴ |
| Apple (native token, no backend) | your server | — | ✅ | — | — | — |
| Facebook (native SDK login) | your server · Firebase · Supabase¹ | ✅ | ✅ | — | — | — |
| GitHub / Microsoft / Facebook-web / any OAuth | Firebase · Supabase | ✅ | ✅ | ✅ | ✅⁴ | ✅⁴ |
| Email (password / reset / magic link) | Firebase · Supabase | ✅ | ✅ | ✅ | ✅ | ✅ |
| Phone number | Firebase · Supabase | ✅ | ✅ | ✅³ | ✅³ | ✅³ |
| Anonymous | Firebase · Supabase | ✅ | ✅ | ✅ | ✅ | ✅ |
¹ Supabase accepts Facebook Limited Login (OIDC) tokens only. Meta's SDK
exists only on Android/iOS — on other platforms use the browser-OAuth row
(rememberOAuthState("facebook.com") with Firebase, or
OAuthWebFlow("facebook.com") with Supabase).
² Firebase on wasm runs on the REST engine (no Firebase SDK there): email,
anonymous, id-token exchange, email link, password reset, reauthentication —
not browser web flows or phone.
³ Beyond Android/iOS only with Supabase (SMS OTP); Firebase phone auth
needs the mobile SDKs.
⁴ Only with Supabase (KMPAuth.signIn(AuthCredential.OAuthWebFlow("github.com"))):
Desktop works out of the box, Android/iOS need Supabase's deep-link setup,
and on web the flow is a full-page redirect — the session is restored after
reload.
Everything compiles and is callable from commonMain on all targets — a
feature unavailable on the current platform reports a failed Result with
the reason instead of not compiling or silently doing nothing.
commonMain.dependencies {
// Identity providers - native SDK sign-in, no backend required:
implementation("io.github.mirzemehdi:kmpauth-google:<version>") // Google sign-in
implementation("io.github.mirzemehdi:kmpauth-apple:<version>") // if needed: native Sign in with Apple (iOS)
implementation("io.github.mirzemehdi:kmpauth-facebook:<version>") // if needed: Facebook login (Android/iOS)
implementation("io.github.mirzemehdi:kmpauth-uihelper:<version>") // if needed: branded sign-in buttons
// Session backend - pick one (or both):
implementation("io.github.mirzemehdi:kmpauth-firebase:<version>") // Firebase backend
implementation("io.github.mirzemehdi:kmpauth-supabase:<version>") // if needed: Supabase backend
}iOS apps add the native SDKs via Swift Package Manager — see Getting started.
Only the provider modules (kmpauth-google, kmpauth-facebook,
kmpauth-apple). The rememberXxxSignInState states hand you the
provider's credential and stop there — send it to your own server:
KMPAuth.initialize {
google(serverId = WebClientId)
}
val googleSignIn = rememberGoogleSignInState(onResult = { result ->
result.onSuccess { googleUser ->
api.login(googleUser.idToken) // verify server-side
}.onFailure { error -> /* cancelled, misconfigured, ... */ }
})
GoogleSignInButton { googleSignIn.launch() }
// same shape for Facebook and native Apple:
val facebookSignIn = rememberFacebookSignInState(onResult = { result: Result<FacebookUser> -> })
val appleSignIn = rememberAppleSignInState(onResult = { result: Result<AppleUser> -> })Add kmpauth-firebase — the backend registers itself, and on Android/iOS
there is zero configuration (the SDK reads google-services.json /
GoogleService-Info.plist). The rememberXxxAuthState states exchange the
credential for a Firebase session; account operations live on KMPAuth:
KMPAuth.initialize {
google(serverId = WebClientId)
// Desktop/Web only - Android/iOS use the bundled config files:
firebase(apiKey = "...", projectId = "...", applicationId = "...")
}
val onResult: (Result<KMPAuthUser>) -> Unit = { result -> /* ... */ }
val googleSignIn = rememberGoogleAuthState(onResult = onResult)
GoogleSignInButton { googleSignIn.launch() }
val appleSignIn = rememberAppleAuthState(onResult = onResult) // native on iOS, web flow elsewhere
val facebookSignIn = rememberFacebookAuthState(onResult = onResult) // kmpauth-facebook, Android/iOS
val githubSignIn = rememberGithubAuthState(onResult = onResult) // browser OAuth web flow
val microsoftSignIn = rememberMicrosoftAuthState(onResult = onResult)
val emailSignIn = rememberEmailAuthState(email, password, onResult = onResult)
val phoneSignIn = rememberPhoneAuthState(phoneNumber, onResult = onResult)
val guestSignIn = rememberAnonymousAuthState(onResult = onResult)
KMPAuth.currentUser()
KMPAuth.signOut()
KMPAuth.sendPasswordResetEmail(email)
KMPAuth.reauthenticate(AuthCredential.EmailPassword(email, password))Add kmpauth-supabase (plus a Ktor client engine per platform — see the
guide) — no Firebase anywhere, works on every target including wasm.
Same states, same KMPAuth operations; only the registration differs:
KMPAuth.initialize {
google(serverId = WebClientId)
supabase(url = projectUrl, apiKey = publishableKey)
}
val onResult: (Result<KMPAuthUser>) -> Unit = { result -> /* ... */ }
val googleSignIn = rememberGoogleAuthState(onResult = onResult) // id-token grant
val facebookSignIn = rememberFacebookAuthState(onResult = onResult) // kmpauth-facebook, Limited Login (OIDC), Android/iOS
val emailSignIn = rememberEmailAuthState(email, password, onResult = onResult)
val phoneSignIn = rememberPhoneAuthState(phoneNumber, onResult = onResult) // SMS OTP, every target
val guestSignIn = rememberAnonymousAuthState(onResult = onResult)
// Same composables as with Firebase - the backend behind them differs:
val appleSignIn = rememberAppleAuthState(onResult = onResult) // native on iOS, browser flow elsewhere
val githubSignIn = rememberGithubAuthState(onResult = onResult) // browser OAuth: Desktop OOTB, mobile via deep links
val microsoftSignIn = rememberMicrosoftAuthState(onResult = onResult)
// ...or any GoTrue provider: rememberOAuthState(provider = "gitlab") /
// KMPAuth.signIn(AuthCredential.OAuthWebFlow("gitlab"))
KMPAuth.sendPasswordResetEmail(email)
KMPAuth.signOut()Need Firebase and Supabase side by side? Register both in
initialize { } (the first — Firebase — stays the default) and scope
subtrees with ProvideKMPAuthBackend("supabase") { ... } —
Custom & multiple backends.
Add kmpauth-uihelper for pre-styled buttons following each brand's
guidelines — they're plain composables, so they wire to any state from the
setups above (and any clickable of your own works instead):
GoogleSignInButton(modifier = Modifier.fillMaxWidth()) { googleSignIn.launch() }
GoogleSignInButtonIconOnly(onClick = { googleSignIn.launch() })
AppleSignInButton(modifier = Modifier.fillMaxWidth()) { appleSignIn.launch() }
AppleSignInButtonIconOnly(onClick = { appleSignIn.launch() })
FacebookSignInButton(modifier = Modifier.fillMaxWidth()) { facebookSignIn.launch() }
FacebookSignInButtonIconOnly(onClick = { facebookSignIn.launch() })Start here — read only what you need:
| Guide | What's in it |
|---|---|
| Getting started | Dependencies, iOS SPM setup, requirements, KMPAuth.initialize, first sign-in |
| Core concepts | The two state layers, KMPAuthUser, the KMPAuth object, account linking, reauthentication |
Identity providers (bring their own SDK/flow, work with any backend or none):
| Guide | Platforms |
|---|---|
| Android · iOS · Desktop · JS · wasm | |
| Apple | Android · iOS (native) · Desktop — or iOS-only without any backend |
| Android · iOS |
Backends & backend-served sign-in (these flows exist only through Firebase/Supabase):
| Guide | What's in it |
|---|---|
| Firebase | Auto-registration, Android/iOS zero-config, Desktop (REST + browser flows), web notes |
| Supabase | Setup, Ktor engines, what maps to Supabase (works on wasm) |
| GitHub / Microsoft / any OAuth | Firebase (Android · iOS · Desktop) or Supabase (every target, see guide) |
| Email — password, reset, magic link | Served by Firebase or Supabase |
| Phone number | Firebase (Android · iOS) or Supabase (every target) |
| Anonymous (guest) | Served by Firebase or Supabase |
| Custom & multiple backends |
AuthProviderBackend, LocalKMPAuthBackend scoping |
Also: UI helper buttons · Full API reference · Sample app covering every feature
Follow the step-by-step MIGRATION.md — most 2.x code keeps
compiling (the *UiContainer composables and GoogleAuthProvider.create
still work, deprecated). All notable changes live in
CHANGELOG.md.
KMPAuth powers FindTravelNow, a production KMP app, so development is actively supported. Related blog post: Integrating Google Sign-In into Kotlin Multiplatform.
Simple and easy-to-use authentication for Compose Multiplatform apps on
Android, iOS, Desktop (JVM) and Web (JS + wasm). Sign in with Google,
Apple, Facebook, GitHub, Microsoft, email/password, magic links, phone
number or anonymously — backed by Firebase or Supabase (or your
own backend), with every API callable from commonMain on every target.
Every sign-in method is served by a backend (or by your own server, when the method just hands you a token). So two questions: which backend runs on your platforms, and which methods that backend serves.
| Backend | Android | iOS | Desktop (JVM) | Web (JS) | Web (wasm) |
|---|---|---|---|---|---|
| Firebase | ✅ | ✅ | ✅ (REST) | ✅ | ✅ (REST²) |
| Supabase | ✅ | ✅ | ✅ | ✅ | ✅ |
("your server" below = no backend needed — the state hands you the provider's token to verify yourself.)
| Sign-in method | Works with | Android | iOS | Desktop (JVM) | Web (JS) | Web (wasm) |
|---|---|---|---|---|---|---|
| your server · Firebase · Supabase | ✅ | ✅ | ✅ | ✅ | ✅ | |
| Apple | Firebase · Supabase | ✅ | ✅ native | ✅ | ✅⁴ | ✅⁴ |
| Apple (native token, no backend) | your server | — | ✅ | — | — | — |
| Facebook (native SDK login) | your server · Firebase · Supabase¹ | ✅ | ✅ | — | — | — |
| GitHub / Microsoft / Facebook-web / any OAuth | Firebase · Supabase | ✅ | ✅ | ✅ | ✅⁴ | ✅⁴ |
| Email (password / reset / magic link) | Firebase · Supabase | ✅ | ✅ | ✅ | ✅ | ✅ |
| Phone number | Firebase · Supabase | ✅ | ✅ | ✅³ | ✅³ | ✅³ |
| Anonymous | Firebase · Supabase | ✅ | ✅ | ✅ | ✅ | ✅ |
¹ Supabase accepts Facebook Limited Login (OIDC) tokens only. Meta's SDK
exists only on Android/iOS — on other platforms use the browser-OAuth row
(rememberOAuthState("facebook.com") with Firebase, or
OAuthWebFlow("facebook.com") with Supabase).
² Firebase on wasm runs on the REST engine (no Firebase SDK there): email,
anonymous, id-token exchange, email link, password reset, reauthentication —
not browser web flows or phone.
³ Beyond Android/iOS only with Supabase (SMS OTP); Firebase phone auth
needs the mobile SDKs.
⁴ Only with Supabase (KMPAuth.signIn(AuthCredential.OAuthWebFlow("github.com"))):
Desktop works out of the box, Android/iOS need Supabase's deep-link setup,
and on web the flow is a full-page redirect — the session is restored after
reload.
Everything compiles and is callable from commonMain on all targets — a
feature unavailable on the current platform reports a failed Result with
the reason instead of not compiling or silently doing nothing.
commonMain.dependencies {
// Identity providers - native SDK sign-in, no backend required:
implementation("io.github.mirzemehdi:kmpauth-google:<version>") // Google sign-in
implementation("io.github.mirzemehdi:kmpauth-apple:<version>") // if needed: native Sign in with Apple (iOS)
implementation("io.github.mirzemehdi:kmpauth-facebook:<version>") // if needed: Facebook login (Android/iOS)
implementation("io.github.mirzemehdi:kmpauth-uihelper:<version>") // if needed: branded sign-in buttons
// Session backend - pick one (or both):
implementation("io.github.mirzemehdi:kmpauth-firebase:<version>") // Firebase backend
implementation("io.github.mirzemehdi:kmpauth-supabase:<version>") // if needed: Supabase backend
}iOS apps add the native SDKs via Swift Package Manager — see Getting started.
Only the provider modules (kmpauth-google, kmpauth-facebook,
kmpauth-apple). The rememberXxxSignInState states hand you the
provider's credential and stop there — send it to your own server:
KMPAuth.initialize {
google(serverId = WebClientId)
}
val googleSignIn = rememberGoogleSignInState(onResult = { result ->
result.onSuccess { googleUser ->
api.login(googleUser.idToken) // verify server-side
}.onFailure { error -> /* cancelled, misconfigured, ... */ }
})
GoogleSignInButton { googleSignIn.launch() }
// same shape for Facebook and native Apple:
val facebookSignIn = rememberFacebookSignInState(onResult = { result: Result<FacebookUser> -> })
val appleSignIn = rememberAppleSignInState(onResult = { result: Result<AppleUser> -> })Add kmpauth-firebase — the backend registers itself, and on Android/iOS
there is zero configuration (the SDK reads google-services.json /
GoogleService-Info.plist). The rememberXxxAuthState states exchange the
credential for a Firebase session; account operations live on KMPAuth:
KMPAuth.initialize {
google(serverId = WebClientId)
// Desktop/Web only - Android/iOS use the bundled config files:
firebase(apiKey = "...", projectId = "...", applicationId = "...")
}
val onResult: (Result<KMPAuthUser>) -> Unit = { result -> /* ... */ }
val googleSignIn = rememberGoogleAuthState(onResult = onResult)
GoogleSignInButton { googleSignIn.launch() }
val appleSignIn = rememberAppleAuthState(onResult = onResult) // native on iOS, web flow elsewhere
val facebookSignIn = rememberFacebookAuthState(onResult = onResult) // kmpauth-facebook, Android/iOS
val githubSignIn = rememberGithubAuthState(onResult = onResult) // browser OAuth web flow
val microsoftSignIn = rememberMicrosoftAuthState(onResult = onResult)
val emailSignIn = rememberEmailAuthState(email, password, onResult = onResult)
val phoneSignIn = rememberPhoneAuthState(phoneNumber, onResult = onResult)
val guestSignIn = rememberAnonymousAuthState(onResult = onResult)
KMPAuth.currentUser()
KMPAuth.signOut()
KMPAuth.sendPasswordResetEmail(email)
KMPAuth.reauthenticate(AuthCredential.EmailPassword(email, password))Add kmpauth-supabase (plus a Ktor client engine per platform — see the
guide) — no Firebase anywhere, works on every target including wasm.
Same states, same KMPAuth operations; only the registration differs:
KMPAuth.initialize {
google(serverId = WebClientId)
supabase(url = projectUrl, apiKey = publishableKey)
}
val onResult: (Result<KMPAuthUser>) -> Unit = { result -> /* ... */ }
val googleSignIn = rememberGoogleAuthState(onResult = onResult) // id-token grant
val facebookSignIn = rememberFacebookAuthState(onResult = onResult) // kmpauth-facebook, Limited Login (OIDC), Android/iOS
val emailSignIn = rememberEmailAuthState(email, password, onResult = onResult)
val phoneSignIn = rememberPhoneAuthState(phoneNumber, onResult = onResult) // SMS OTP, every target
val guestSignIn = rememberAnonymousAuthState(onResult = onResult)
// Same composables as with Firebase - the backend behind them differs:
val appleSignIn = rememberAppleAuthState(onResult = onResult) // native on iOS, browser flow elsewhere
val githubSignIn = rememberGithubAuthState(onResult = onResult) // browser OAuth: Desktop OOTB, mobile via deep links
val microsoftSignIn = rememberMicrosoftAuthState(onResult = onResult)
// ...or any GoTrue provider: rememberOAuthState(provider = "gitlab") /
// KMPAuth.signIn(AuthCredential.OAuthWebFlow("gitlab"))
KMPAuth.sendPasswordResetEmail(email)
KMPAuth.signOut()Need Firebase and Supabase side by side? Register both in
initialize { } (the first — Firebase — stays the default) and scope
subtrees with ProvideKMPAuthBackend("supabase") { ... } —
Custom & multiple backends.
Add kmpauth-uihelper for pre-styled buttons following each brand's
guidelines — they're plain composables, so they wire to any state from the
setups above (and any clickable of your own works instead):
GoogleSignInButton(modifier = Modifier.fillMaxWidth()) { googleSignIn.launch() }
GoogleSignInButtonIconOnly(onClick = { googleSignIn.launch() })
AppleSignInButton(modifier = Modifier.fillMaxWidth()) { appleSignIn.launch() }
AppleSignInButtonIconOnly(onClick = { appleSignIn.launch() })
FacebookSignInButton(modifier = Modifier.fillMaxWidth()) { facebookSignIn.launch() }
FacebookSignInButtonIconOnly(onClick = { facebookSignIn.launch() })Start here — read only what you need:
| Guide | What's in it |
|---|---|
| Getting started | Dependencies, iOS SPM setup, requirements, KMPAuth.initialize, first sign-in |
| Core concepts | The two state layers, KMPAuthUser, the KMPAuth object, account linking, reauthentication |
Identity providers (bring their own SDK/flow, work with any backend or none):
| Guide | Platforms |
|---|---|
| Android · iOS · Desktop · JS · wasm | |
| Apple | Android · iOS (native) · Desktop — or iOS-only without any backend |
| Android · iOS |
Backends & backend-served sign-in (these flows exist only through Firebase/Supabase):
| Guide | What's in it |
|---|---|
| Firebase | Auto-registration, Android/iOS zero-config, Desktop (REST + browser flows), web notes |
| Supabase | Setup, Ktor engines, what maps to Supabase (works on wasm) |
| GitHub / Microsoft / any OAuth | Firebase (Android · iOS · Desktop) or Supabase (every target, see guide) |
| Email — password, reset, magic link | Served by Firebase or Supabase |
| Phone number | Firebase (Android · iOS) or Supabase (every target) |
| Anonymous (guest) | Served by Firebase or Supabase |
| Custom & multiple backends |
AuthProviderBackend, LocalKMPAuthBackend scoping |
Also: UI helper buttons · Full API reference · Sample app covering every feature
Follow the step-by-step MIGRATION.md — most 2.x code keeps
compiling (the *UiContainer composables and GoogleAuthProvider.create
still work, deprecated). All notable changes live in
CHANGELOG.md.
KMPAuth powers FindTravelNow, a production KMP app, so development is actively supported. Related blog post: Integrating Google Sign-In into Kotlin Multiplatform.