Installation
This guide gets your build ready to use StoatFlow: wire up the private Maven repository with your credentials, add the dependency, and configure the JVM toolchain. Then configure your license and build your first app.
Prerequisites
- JDK 25 or newer. StoatFlow uses JDK preview features (virtual threads, structured concurrency), so a 25+ toolchain is mandatory — not just for building, but at runtime.
- Apache Kafka 4.x, reachable from where you run the app. For local development the quickest option is a single-node KRaft broker via Docker (
localhost:9092). - Your onboarding email. It contains your read-only Maven token (username
customer-<your-slug>+ secret) and your license key. Don't have one yet? Get in touch.
~/.gradle/gradle.properties, ~/.m2/settings.xml), never in a file you commit.1. Register the private Maven repository
StoatFlow artifacts are served from a private, authenticated repository at https://maven.stoatflow.io/releases. You can wire it up two ways — directly on each developer machine (below), or once through your corporate artifact manager.
https://maven.stoatflow.io/releases as a remote / proxy repository and surface it through the virtual (group) repository your developers already resolve against. That way:- your StoatFlow token is configured once, centrally — never copied onto individual machines;
- developers need no local credentials and no build changes — they resolve through the corporate repo exactly as they do today;
- dependencies (and the
io.stoatflowGradle plugin) pull through and cache via the proxy, with authentication handled there.
Store your credentials
# ~/.gradle/gradle.properties — your HOME dir, never committed
stoatflowRepoUser=customer-your-slug
stoatflowRepoToken=PASTE_YOUR_MAVEN_TOKEN_FROM_THE_ONBOARDING_EMAIL
<!-- ~/.m2/settings.xml — your HOME dir, never committed -->
<settings>
<servers>
<server>
<id>stoatflow-releases</id>
<username>customer-your-slug</username>
<password>PASTE_YOUR_MAVEN_TOKEN_FROM_THE_ONBOARDING_EMAIL</password>
</server>
</servers>
</settings>
Point your build at the repository
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
mavenCentral()
maven {
url = uri("https://maven.stoatflow.io/releases")
credentials {
username = providers.gradleProperty("stoatflowRepoUser").get()
password = providers.gradleProperty("stoatflowRepoToken").get()
}
}
}
}
<!-- pom.xml -->
<repositories>
<repository>
<id>stoatflow-releases</id>
<url>https://maven.stoatflow.io/releases</url>
<releases><enabled>true</enabled></releases>
</repository>
</repositories>
The <id> in pom.xml must match the <server><id> in settings.xml — that's how Maven applies your credentials.
2. Add the dependency
Most applications want stoatflow-runtime — the batteries-included wrapper (YAML config, HTTP admin + health endpoints, Prometheus metrics, graceful shutdown). It transitively pulls in stoatflow-core, so it's the only dependency you need. If you want just the DSL and engine with no runtime scaffolding, depend on stoatflow-core instead.
// build.gradle.kts
dependencies {
implementation("io.stoatflow:stoatflow-runtime:$stoatflowVersion")
// ...or DSL only:
// implementation("io.stoatflow:stoatflow-core:$stoatflowVersion")
// In-memory topology testing (no broker required):
testImplementation("io.stoatflow:stoatflow-test-utils:$stoatflowVersion")
}
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>io.stoatflow</groupId>
<artifactId>stoatflow-runtime</artifactId>
<version>${stoatflow.version}</version>
</dependency>
<!-- In-memory topology testing (no broker required): -->
<dependency>
<groupId>io.stoatflow</groupId>
<artifactId>stoatflow-test-utils</artifactId>
<version>${stoatflow.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
1.0.0-alpha.2 — set it as stoatflowVersion in gradle.properties (or <stoatflow.version> in pom.xml), or use the exact version from your onboarding email if it differs. The published modules are stoatflow-core, stoatflow-runtime, stoatflow-test-utils, and stoatflow-test-runtime, all under group io.stoatflow.3. Configure the JVM toolchain
StoatFlow needs a JDK 25 toolchain and two JVM flags at both compile and run time:
--enable-preview— StoatFlow is built on JDK preview features.--enable-native-access=ALL-UNNAMED— RocksDB's state store uses the Foreign Function & Memory API.-XX:+UseG1GCkeeps GC pauses short and predictable — which matters for stream processing, where a long stop-the-world pause stalls commit barriers and inflates end-to-end latency. The JVM only auto-selects G1 on "server-class" hardware (≥ 2 CPUs and ≥ ~2 GB of memory), falling back to the single-threaded Serial collector below that — so set it explicitly to get consistent pause behaviour even on a single core or a small container. (Theio.stoatflowGradle plugin already applies this flag to the Docker image it builds.)
Option A — the io.stoatflow Gradle plugin (recommended)
The convention plugin applies the JDK 25 toolchain, the preview + native-access JVM args (compile, test, and run), and a runnable fat-jar (shadow) — so you don't hand-maintain any of it. It's Gradle-only (Maven projects use Option B).
Add a pluginManagement repository for the plugin marker in settings.gradle.kts:
// settings.gradle.kts
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
maven {
url = uri("https://maven.stoatflow.io/releases")
credentials {
username = providers.gradleProperty("stoatflowRepoUser").get()
password = providers.gradleProperty("stoatflowRepoToken").get()
}
}
}
}
Then apply it in build.gradle.kts:
// build.gradle.kts
plugins {
kotlin("jvm") version "2.3.21" // omit for a Java-only project
id("io.stoatflow") version "$stoatflowVersion"
}
stoatflow {
mainClass.set("com.example.MainKt") // your application entry point
}
Option B — configure it yourself
If you'd rather not use the plugin, set the toolchain and JVM args directly:
// build.gradle.kts
java {
toolchain { languageVersion = JavaLanguageVersion.of(25) }
}
tasks.withType<JavaCompile> { options.compilerArgs.add("--enable-preview") }
application {
applicationDefaultJvmArgs = listOf(
"--enable-preview",
"--enable-native-access=ALL-UNNAMED",
"-XX:+UseG1GC",
)
}
<!-- pom.xml -->
<properties>
<maven.compiler.release>25</maven.compiler.release>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs><arg>--enable-preview</arg></compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
<!-- Run with: java --enable-preview --enable-native-access=ALL-UNNAMED -XX:+UseG1GC -jar your-app.jar -->
Next steps
- License configuration — every license env var / system property / YAML key, for local development and CI/CD.
- Your first app — build and run a complete word-count app on the runtime.
- Architecture — the single-instance model, lane dispatcher, and commit barriers.
- Stuck? Get in touch — real people read every email during the alpha.