Dart VM Extension Development
Applies to FlutterX versions that expose the
dartVmDevToolextension point
FlutterX exposes Dart VM ToolWindow tabs through the shop.itbug.FlutterCheckVersionX.dartVmDevTool extension point. The built-in Vm, Memory, Http Monitor, Logging, Provider, Shared Preferences, Hive CE, and Drift DB tabs are registered through the same extension point that third-party plugins can use.
Registration
A third-party plugin must depend on FlutterX and register dartVmDevTool under the FlutterX namespace.
<depends>shop.itbug.FlutterCheckVersionX</depends>
<extensions defaultExtensionNs="shop.itbug.FlutterCheckVersionX">
<dartVmDevTool
id="myTool"
implementation="com.example.MyDartVmDevTool"
descriptionKey="my.tool.description"
order="after hive"/>
</extensions>
Attributes
| Attribute | Required | Description |
|---|---|---|
id |
Yes | Stable tab ID. FlutterX stores hidden tab settings by this value, so avoid changing it after publishing. |
implementation |
Yes | Class that implements shop.itbug.flutterx.api.vm.DartVmDevToolExtension. |
descriptionKey |
No | I18n key resolved from the contributing plugin resource bundle and shown in the Dart VM settings page. |
order |
No | IntelliJ extension ordering, for example first, last, after hive, or before drift. |
If descriptionKey is omitted or cannot be resolved, FlutterX simply does not show a description.
Implementing a Tool
Keep extension classes stateless and avoid heavy work in constructors. Put UI setup and Dart VM Service access into the component lifecycle created by createComponent.
package com.example
import com.intellij.openapi.project.Project
import shop.itbug.flutterx.api.vm.DartVmDevToolContext
import shop.itbug.flutterx.api.vm.DartVmDevToolExtension
import java.awt.BorderLayout
import javax.swing.JComponent
import javax.swing.JLabel
import javax.swing.JPanel
class MyDartVmDevTool : DartVmDevToolExtension {
override fun getTabTitle(project: Project): String = "My Tool"
override fun isAvailable(context: DartVmDevToolContext): Boolean {
return true
}
override fun createComponent(context: DartVmDevToolContext): JComponent {
return JPanel(BorderLayout()).apply {
add(JLabel("My FlutterX Dart VM tool"), BorderLayout.CENTER)
}
}
}
createComponent returns a Swing JComponent. FlutterX does not expose Compose or Jewel types as public API, which keeps third-party plugins less sensitive to Kotlin, Compose, and Jewel version changes.
Reading Running Flutter Apps
DartVmDevToolContext exposes the current project, the ToolWindow, and the live list of running Flutter apps.
interface DartVmDevToolContext {
val project: Project
val toolWindow: ToolWindow
val runningApps: StateFlow<List<DartVmApp>>
}
runningApps is live state. If the user opens the FlutterX Dart VM ToolWindow before starting a Flutter app, your component should subscribe to context.runningApps to receive updates.
interface DartVmApp {
val appId: String
val vmUrl: String
val deviceId: String
val mode: String
val vmService: VmService
}
Use DartVmApp.vmService to call Dart VM Service RPCs. These calls may be slow or fail, so do not block the EDT.
Localized Description
To show a description in the Dart VM settings page, set descriptionKey and provide the text in your plugin resource bundle.
<idea-plugin>
<resource-bundle>messages.MyPluginBundle</resource-bundle>
<depends>shop.itbug.FlutterCheckVersionX</depends>
<extensions defaultExtensionNs="shop.itbug.FlutterCheckVersionX">
<dartVmDevTool
id="myTool"
implementation="com.example.MyDartVmDevTool"
descriptionKey="my.tool.description"
order="after hive"/>
</extensions>
</idea-plugin>
Showing and Hiding Tabs
FlutterX automatically lists all registered Dart VM tabs in the Dart VM settings page, including third-party tabs. Tabs are shown by default. When the user clears the checkbox, the tab is hidden.
Hidden state is stored by extension id. Do not change a published id unless you accept resetting user visibility preferences.
Notes
- v1 does not refresh already-open Dart VM tabs immediately when a third-party plugin is installed or uninstalled. Reopen the ToolWindow or restart the IDE.
- If one extension fails while creating its component, FlutterX skips that tab and continues loading the others.
- Use
isAvailablewhen a tab should only appear for certain projects, dependencies, or runtime states. - Components should release their own listeners, coroutines, and VM Service subscriptions.
Validation
Recommended checks for third-party extensions:
./gradlew compileKotlinpasses../gradlew verifyPluginStructurepasses.- The third-party tab appears in FlutterX Dart VM.
- Ordering such as
order="after hive"works. - If the ToolWindow is opened before the Flutter app starts, UI subscribed to
runningAppsupdates correctly. - Hiding the tab in Dart VM settings removes it, and showing it again restores it.