Introduction
KMPwright is a Kotlin Multiplatform browser automation library with a Playwright-style API and agent-browser commands for Android WebView, iOS WKWebView and Chromium on the JVM.
KMPwright lets you write browser automation once, in shared Kotlin, and run it against:
- an Android
WebViewyour app already shows, - an iOS
WKWebViewyour app already shows, - a Chromium you launch or connect to over the Chrome DevTools Protocol (CDP) on the JVM.
The API follows Playwright names (goto, locator, getByRole, fill, expect, route) and adds the agent features of Vercel's agent-browser: accessibility snapshots with @e refs, page.runCommand("click @e3"), allowed domains, action policies and content boundaries.
Version 0.0.1 is available on Maven Central. This is an alpha release; APIs and platform coverage may change. See Installation.
Who it is for
- App developers who embed web content and want to test, drive or inspect it from Kotlin on the device itself.
- Agent builders who want to give an LLM a browser tool inside a mobile app or a JVM service, using the same command grammar as agent-browser.
- Playwright users writing Kotlin Multiplatform code who want familiar names and semantics.
The 30-second example
The same Page works on every backend. An agent drives it with text commands; your code drives it with typed calls.
// Hand this to an LLM as a single "browser" tool.
page.runCommand("open example.com")
val snapshot = page.runCommand("snapshot -i")
println(snapshot.output)
// @e1 [heading] "Example Domain" [level=1]
// @e2 [link] "Learn more"
page.runCommand("click @e2")
println(page.runCommand("get title").output)runCommand accepts the documented subset of agent-browser commands, returns plain text for the model in output, and also returns structured data (snapshot, screenshot) when a command produces it. See Coming from agent-browser for the supported commands.
How you get a page
| Backend | Entry point | Page source |
|---|---|---|
Android WebView | Browser(AndroidPlatformContext(activity, webView)) | browser.page() attaches to your WebView |
iOS WKWebView | Browser(IOSPlatformContext(webView = webView)) | browser.page() attaches to your WKWebView |
| JVM Chromium (owned) | launchBrowser(executablePath) | launched.browser.newPage() |
| JVM Chromium (existing or cloud) | Browser(JvmPlatformContext(), KmpwrightConfig(cdp = CdpConfig(...))) | browser.newPage() or browser.attachTarget(id) |
Step-by-step setup is in the Quick start.
What works where
Most APIs live in commonMain and run on every backend. Where a backend can only do part of the job, page.capabilities() reports it as Supported, Partial or Unsupported, with human-readable notes that explain the gap. Check them before a workflow starts with page.requireCapabilities(...).
| Area | Android WebView | iOS WKWebView | JVM Chromium (CDP) |
|---|---|---|---|
| Locators, actions, assertions, snapshots | Yes (DOM input) | Yes (DOM input) | Yes (trusted CDP input) |
| Keyboard / mouse / touch | Supported / Partial / Supported | Partial / Partial / Partial | Supported / Supported / Partial |
Request routing (route) | Partial | Partial | Supported |
| Allowed domains | Partial | Supported | Supported |
| Isolated browser contexts | Unsupported | Partial | Supported |
| Init scripts | Partial | Supported | Supported |
| Network throttling | Partial (offline only) | Partial (offline only) | Supported |
| Downloads, file chooser | Unsupported | Unsupported | Supported, Partial |
| Tracing, profiling, video, screencast | Unsupported | Unsupported | Supported |
| Partial | Partial | Partial |
The full matrix, with each capability's notes, is in Capabilities.
Where to go next
Installation
Add KMPwright to a Kotlin Multiplatform, Android, iOS or JVM project.
Quick start
Attach to a WebView or launch Chromium, then act, assert and screenshot.
Sample app
Run the Compose Multiplatform demo on Android and iOS.
Coming from Playwright
Playwright JS to KMPwright mapping, and what differs.
Coming from agent-browser
CLI commands and flags mapped to runCommand and the Kotlin API.
Agents
Snapshots, refs, commands and LLM tool wiring.
Security
Origin rules, action policies, allowed domains and content boundaries.