GraalVM native-image
curie native compiles your project to a standalone native binary using GraalVM's native-image tool. The result starts in milliseconds, uses a fraction of the heap, and ships without a JVM — ideal for serverless functions, CLI tools, and containers where image size and cold-start time matter.
Prerequisites
GraalVM (Community or Enterprise) must be installed and native-image must be on PATH. The easiest way is SDKMAN:
$ sdk install java 21.0.3-graalce $ native-image --version native-image 21.0.3 2024-04-16
Configuration
Add a [native-image] table. An empty table is enough to enable the step — all keys are optional:
[application] name = "my-cli" version = "0.1.0" mainClass = "com.example.Main" [native-image] # Output binary name (default: application name) outputName = "my-cli" # Path to reachability-metadata config dir configDir = "src/main/resources/META-INF/native-image" # Extra flags forwarded verbatim to native-image extraArgs = ["--no-fallback", "-H:+ReportExceptionStackTraces"]
Building
curie native compiles the project (skipping tests for a faster iteration loop) and then invokes native-image:
Building my-cli v0.1.0 Resolve deps 3 JAR(s) Compile 4 source file(s) Package my-cli-0.1.0.jar Native image my-cli (GraalVM native-image) …compiling… ~1–2 minutes… Done target/my-cli
The binary lands at target/<outputName>. Run it directly — no JVM needed:
my-cli 0.1.0
Usage: my-cli [options]
Integration with curie build
When [native-image] is present in Curie.toml, curie build also compiles the native binary after packaging the JAR and running tests. Pass --no-native to skip it when iterating quickly:
Building my-cli v0.1.0 … (native-image step skipped) Done target/my-cli-0.1.0.jar
Reachability metadata
Frameworks that use reflection, dynamic proxies, or resources at runtime need GraalVM reachability metadata so the AOT compiler knows to include those classes. Place JSON configuration files in the directory declared by configDir:
reflect-config.json— classes accessed via reflectionresource-config.json— resources loaded from the classpathproxy-config.json— dynamic proxy interfaces
The GraalVM reachability-metadata repository already contains entries for many popular libraries.