PostHog KMP

A Kotlin Multiplatform SDK for PostHog analytics, supporting Android, iOS, Web (JS/Wasm), JVM, and macOS.
Features
Supported Platforms
Feature Flag API Parity
Installation
Gradle (Kotlin DSL)
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.samuolis:posthog-kmp:<version>")
}
}
}
Version Catalog
[versions]
posthog-kmp = "<version>"
[libraries]
posthog-kmp = { group = "io.github.samuolis", name = "posthog-kmp", version.ref = "posthog-kmp" }
Quick Start
Initialize PostHog
import io.github.samuolis.posthog.PostHog
import io.github.samuolis.posthog.PostHogConfig
import io.github.samuolis.posthog.PostHogContext
PostHog.setup(
config = PostHogConfig(
apiKey = "phc_your_api_key",
debug = true
),
context = PostHogContext()
)
PostHog.setup(
config = PostHogConfig(
apiKey = "phc_your_api_key",
host = PostHogConfig.HOST_EU,
debug = BuildConfig.DEBUG,
captureApplicationLifecycleEvents = ,
captureScreenViews = ,
preloadFeatureFlags =
),
context = PostHogContext()
)
Platform-Specific Setup
Android
On Android, pass the Application context to PostHogContext:
import io.github.samuolis.posthog.PostHog
import io.github.samuolis.posthog.PostHogConfig
import io.github.samuolis.posthog.PostHogContext
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
PostHog.setup(
config = PostHogConfig(apiKey = ),
context = PostHogContext(application)
)
}
}
iOS / Web / JVM / macOS
On non-Android platforms, use the no-argument PostHogContext():
fun MainViewController() = ComposeUIViewController {
LaunchedEffect(Unit) {
PostHog.setup(
config = PostHogConfig(apiKey = "phc_your_api_key"),
context = PostHogContext()
)
}
App()
}
fun main() {
PostHog.setup(
config = PostHogConfig(apiKey = "phc_your_api_key"),
context = PostHogContext()
)
}
Capture Events
PostHog.capture("button_clicked")
PostHog.capture(
event = "purchase_completed",
properties = mapOf(
"product_id" to "SKU123",
"price" to 29.99,
"currency" to "USD"
)
)
PostHog.capture(
event = "feature_used",
properties = mapOf( to ),
options = CaptureOptions(groups = mapOf( to ))
)
Identify Users
PostHog.identify("user_123")
PostHog.identify(
distinctId = "user_123",
userProperties = mapOf(
"email" to "user@example.com",
"name" to "John Doe",
"plan" to "premium"
)
)
PostHog.identify(
distinctId = ,
userPropertiesSetOnce = mapOf(
to ,
to
)
)
PostHog.reset()
Feature Flags
Group Analytics
PostHog.group(
type = "company",
key = "acme_corp",
groupProperties = mapOf(
"name" to "Acme Corporation",
"plan" to "enterprise",
"employee_count" to 500
)
)
PostHog.group("company", "acme_corp")
PostHog.group("team", "engineering")
Screen/Page Tracking
PostHog.screen("Home")
PostHog.screen(
screenName = "Product Details",
properties = mapOf(
"product_id" to "SKU123",
"category" to "Electronics"
)
)
Error Tracking
try {
riskyOperation()
} catch (e: Exception) {
PostHog.captureException(
throwable = e,
level = ExceptionLevel.ERROR,
additionalProperties = mapOf(
"context" to "checkout_flow",
"user_action" to "submit_payment"
)
)
}
Session Recording
Session recording is available on Android and iOS platforms.
Session Management
val anonymousId = PostHog.getAnonymousId()
val sessionId = PostHog.getSessionId()
val distinctId = PostHog.getDistinctId()
Super Properties
PostHog.register("app_version", "2.0.0")
PostHog.register("platform", "mobile")
PostHog.registerAll(mapOf(
"environment" to "production",
"build_number" to 142
))
PostHog.unregister("temporary_flag")
Privacy Controls
if (PostHog.isOptedOut()) {
showConsentBanner()
}
PostHog.optOut()
PostHog.optIn()
Flush & Close
PostHog.flush()
PostHog.close()
Configuration Options
Session Recording Options
Platform-Specific Notes
Android
- Uses official PostHog Android SDK (
posthog-android 3.30.0+)
- Requires
PostHogContext(application) with Application context
- Session recording with wireframe or screenshot mode
- Automatic lifecycle tracking
- Deep link capture
- Logcat capture support
getAllFeatureFlags() returns the in-memory set of observed and locally overridden flags
iOS
- Uses official PostHog iOS SDK (3.38.0+) via Swift bridge
- Full native SDK features including:
- Session recording (wireframe or screenshot mode)
- Surveys (iOS 15+)
- Autocapture
- Native networking and caching
- Network telemetry capture
getAllFeatureFlags() returns the in-memory set of observed and locally overridden flags
macOS
- Currently stub implementation
- Native SDK support planned for future release
JVM
- Uses Ktor HTTP client with OkHttp engine
- Suitable for server-side Kotlin applications
- Coroutine-based async operations
- Periodic flush with configurable intervals
- Feature-flag API is best-effort and optimized for server-side use, not full native parity
JS/Wasm
- Wraps official posthog-js library (1.328.0+)
- Full browser feature support
- Session recording available
- LocalStorage persistence
- Autocapture support
- Wasm
getAllFeatureFlags() is mapped from posthog-js getAllFlags() and merged with local overrides
Contributing
Contributions are welcome!
Development Setup
git clone https://github.com/samuolis/posthog-kmp.git
cd posthog-kmp
./gradlew build
./gradlew allTests
License
Acknowledgements
- PostHog - The open source product analytics platform
- Kotlin Multiplatform - Cross-platform development
Resources