
Real-time visualizer for coroutine call trees, tracking function calls, suspension/resume points, exceptions and cancellation propagation; includes compiler instrumentation, event-stream export and customizable GUI themes.
Educational tool for visualizing Kotlin Coroutine execution.
This project is designed as an educational resource, specifically targeted at coroutine-related talks, workshops, and for anyone wanting to build a deeper mental model of how coroutines behave. It provides a real-time GUI that visualizes coroutine call trees, tracking function calls, exceptions, and cancellations across coroutines.
This tool is especially useful for live demonstrations during talks or workshops. By visualizing the call tree, you can:
:compiler-plugin: The Kotlin compiler plugin that instruments code for tracking.:gradle-plugin: A Gradle plugin to easily apply the compiler plugin to your projects.:stack-tracking-core-api: The runtime API used by instrumented code.:tracked-call-tree-as-flow: Integration layer that converts tracking events into a Kotlin Flow.:call-tree-visualizer-gui: A Compose Multiplatform desktop application for visualizing the call tree.:examples: Example project demonstrating how to use the visualizer.The compiler plugin transforms every suspend function (unless marked with @NonTracked) to wrap its body with a call to stackTracked. This function uses a StackTrackingContext from the CoroutineContext to report when a function is entered, exited, or when it throws an exception.
Add the plugin to your settings.gradle.kts:
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}And in your build.gradle.kts:
plugins {
id("com.woutwerkman.calltreevisualizer") version "0.0.1-2.2.20"
}By default, all suspend functions are instrumented. You can opt-out of tracking for specific functions using the @NonTracked annotation:
@NonTracked
suspend fun internalWork() {
// This function won't appear in the call tree
}You can use the trackingCallStacks function to collect events as a Flow:
// Will print:
// Event type: CallStackPushType of function named fully.qualified.name.of.foo
// Event type: CallStackPopType of function named fully.qualified.name.of.foo
suspend fun main() {
trackingCallStacks {
foo()
}.collect {
println("Event type: ${it.eventType} of function named ${it.node.functionFqn}")
}
}For more advanced usage, see the detailed READMEs in the subprojects:
You can use the trackingCallStacks function from the :tracked-call-tree-as-flow module to collect events and display them in the CallTreeUI provided by the :call-tree-visualizer-gui module.
See examples/src/main/kotlin/com/woutwerkman/calltreevisualizer/Main.kt for a complete example.
./gradlew buildThe project uses the Kotlin compiler test framework.
compiler-plugin/testData/box
compiler-plugin/testData/diagnostics
Run tests with:
./gradlew :compiler-plugin:testNote: This is an educational project and is not intended for production use. It is optimized for clarity and visualization during presentations rather than performance.
Developed as a tool to better understand and explain complex Kotlin Coroutine interactions.
Educational tool for visualizing Kotlin Coroutine execution.
This project is designed as an educational resource, specifically targeted at coroutine-related talks, workshops, and for anyone wanting to build a deeper mental model of how coroutines behave. It provides a real-time GUI that visualizes coroutine call trees, tracking function calls, exceptions, and cancellations across coroutines.
This tool is especially useful for live demonstrations during talks or workshops. By visualizing the call tree, you can:
:compiler-plugin: The Kotlin compiler plugin that instruments code for tracking.:gradle-plugin: A Gradle plugin to easily apply the compiler plugin to your projects.:stack-tracking-core-api: The runtime API used by instrumented code.:tracked-call-tree-as-flow: Integration layer that converts tracking events into a Kotlin Flow.:call-tree-visualizer-gui: A Compose Multiplatform desktop application for visualizing the call tree.:examples: Example project demonstrating how to use the visualizer.The compiler plugin transforms every suspend function (unless marked with @NonTracked) to wrap its body with a call to stackTracked. This function uses a StackTrackingContext from the CoroutineContext to report when a function is entered, exited, or when it throws an exception.
Add the plugin to your settings.gradle.kts:
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}And in your build.gradle.kts:
plugins {
id("com.woutwerkman.calltreevisualizer") version "0.0.1-2.2.20"
}By default, all suspend functions are instrumented. You can opt-out of tracking for specific functions using the @NonTracked annotation:
@NonTracked
suspend fun internalWork() {
// This function won't appear in the call tree
}You can use the trackingCallStacks function to collect events as a Flow:
// Will print:
// Event type: CallStackPushType of function named fully.qualified.name.of.foo
// Event type: CallStackPopType of function named fully.qualified.name.of.foo
suspend fun main() {
trackingCallStacks {
foo()
}.collect {
println("Event type: ${it.eventType} of function named ${it.node.functionFqn}")
}
}For more advanced usage, see the detailed READMEs in the subprojects:
You can use the trackingCallStacks function from the :tracked-call-tree-as-flow module to collect events and display them in the CallTreeUI provided by the :call-tree-visualizer-gui module.
See examples/src/main/kotlin/com/woutwerkman/calltreevisualizer/Main.kt for a complete example.
./gradlew buildThe project uses the Kotlin compiler test framework.
compiler-plugin/testData/box
compiler-plugin/testData/diagnostics
Run tests with:
./gradlew :compiler-plugin:testNote: This is an educational project and is not intended for production use. It is optimized for clarity and visualization during presentations rather than performance.
Developed as a tool to better understand and explain complex Kotlin Coroutine interactions.