Existing Plugins¶
Livewire ships with a set of first-party plugins. All plugin artifacts are published under the com.livewire-kt.livewire group and support Android, JVM (Desktop), and iOS unless noted.
| Plugin | Artifact | What it does |
|---|---|---|
| Database | plugin-database |
Browse SQLite databases on-device and run queries |
| Network | plugin-network-core (+ -ktor / -okhttp) |
Inspect HTTP traffic from Ktor and OkHttp clients |
| Preferences | plugin-preferences |
View and live-edit SharedPreferences, DataStore, NSUserDefaults, and java.util.prefs |
| Recomposition | plugin-recomposition |
Live recomposition counts and invalidation reasons |
| Playground | (not published) | Widget catalog used for developing Livewire itself |
Database¶
A raw SQLite inspector. It works with any SQLite database file, regardless of what created it (SQLDelight, Room, raw SQLite, etc). Browse databases and tables, view schemas, and run SQL queries; SELECT / PRAGMA / EXPLAIN statements are detected and run read-only.
The constructor is platform-specific, reflecting how databases are located on each platform:
Network¶
The network inspector comes in two parts: the plugin that renders the request list in the host, and an integration that hooks into your HTTP client and records traffic.
Install the plugin:
Then add an integration for each HTTP client your app uses:
Add livewire-plugins-network-ktor and install the Ktor client plugin:
Both integrations feed the same collector, so requests from multiple clients appear in one unified timeline. Request and response bodies are captured up to maxBodySize (256 KiB by default).
Preferences¶
A key/value store inspector. View and live-edit your app's preferences from the host. Edits are written through the real store APIs in your running app, and changes your app makes appear in the host immediately via each store's native change mechanism (OnSharedPreferenceChangeListener, DataStore.data, NSUserDefaultsDidChangeNotification, PreferenceChangeListener).
The constructor is platform-specific, reflecting how stores are located on each platform:
DataStore enforces a single instance per file, so DataStores are never discovered — register the live instances your app already uses via the trailing lambda:
install(
PreferencesPlugin(context) {
// Full read/write inspection of a Preferences DataStore
dataStore("settings", settingsDataStore)
// Read-only view of any typed DataStore, rendered by the lambda
protoDataStore("session", sessionStore) { Json.encodeToString(it) }
}
)
In the host: filter entries by key, toggle booleans with a switch, and edit everything else inline — commit with the check button or Enter, cancel with Esc. Edits are drafts until committed, so nothing is written while you type, and invalid input (e.g. abc for an Int) shows an inline error instead of writing. New entries can be added with any type the selected store supports; deleting a key or clearing a store uses a two-step confirm. String sets are edited one entry per line, byte arrays as Base64.
| Store | Discovery | Types |
|---|---|---|
| SharedPreferences (Android) | Automatic | String, Int, Long, Float, Boolean, StringSet |
| Preferences DataStore | Registered | String, Int, Long, Float, Double, Boolean, StringSet, Bytes |
| NSUserDefaults (iOS) | Standard + registered suites | String, Long, Double, Boolean, StringSet, Bytes |
| java.util.prefs (Desktop) | Registered node paths | String |
| Proto DataStore | Registered | Read-only rendered view |
Platform quirks
NSUserDefaults types are best-effort — NSNumber doesn't preserve the exact Kotlin type, so integers surface as Long and floating-point values as Double, and change notifications only fire for in-process writes. java.util.prefs values are string-typed on read-back, so everything there is presented as a String.
Recomposition¶
Live Compose performance tooling: per-composable recomposition, skip, and child-recomposition counts rendered as an expandable tree, with a detail panel showing invalidation reasons and parameter changes.
The constructor exposes tuning knobs:
RecompositionPlugin(
alwaysOnSampling = false, // if false, tracking only runs while the plugin is open
recompositionThresholds = RecompositionThresholds(low = 2, moderate = 5, high = 10),
)
Initialization
Recomposition tracking hooks Compose source information, which must be enabled before the first composition. On Android this happens automatically via androidx.startup; on other platforms it's handled when the plugin is constructed. Just construct it early (before your first frame).
iOS Details
Due to the lack of reflection in Kotlin/Native, a bit less detail is available when using the recomposition plugin on the iOS platform.
Playground¶
An internal widget catalog exercising every Livewire widget: buttons, chips, text fields, sliders, tabs, tables, animations, and a crash-test button. It isn't published as an artifact, but it's the best reference for what the UI system can do and a good template for your own plugin: plugins/playground.