elide.pkl is the project manifest: it declares builds, dependencies, tests and artifacts. Every file starts with:
amends "elide:project.pkl"
elide: resolves to the schema bundled with the running Elide, for this and every other module (elide:Jvm.pkl).
To pin a schema version, amend the published URL:
pkl.elide.dev/1.6.3/project.pkl.
Schema versions are independent of the Elide runtime version. A development schema can be locked before it is
published; the URL above stays on a published version. Published development versions follow main until their
stable release, after which they are immutable.
Patch releases within a MAJOR.MINOR line only add properties. A minor release can remove, rename or retype
properties and change defaults.
| Pinned version | Result |
|---|---|
| Older than the bundled schema | Uses that version; a property removed since fails, naming the version. |
| Newer than the bundled schema | Allowed; a property the running Elide lacks fails, naming the upgrade. |
| Another major version | Refused. |
elide project export prints the evaluated manifest as JSON; elide build --inspect lists its tasks.
Project metadata
| Property | Purpose |
|---|---|
name, version, description | Project identity; version also names application archives. |
entrypoint | File(s) elide run uses when given none. |
scripts | Named shell commands for elide run NAME. |
sources | Source sets; see Sources. |
dependencies | Maven, npm and PyPI packages; see Dependencies. |
jvm, kotlin, javascript | Language and compiler settings. |
nativeImage | Accepted and not applied; set each artifact’s options. |
engine | Serving contexts; see Engine contexts. |
toolchain | Accepted Elide versions; see Toolchain. |
dev | Source info, MCP, dev server; see Dev. |
web | Web asset settings; see Web. |
artifacts | Build outputs; see Artifacts. |
testing | Test reports; see Testing. |
coverage | Coverage; see Testing › Coverage. |
workspace | Member projects; see Workspaces. |
build.flags holds the -f/--flag values; see Build Flags.
Engine contexts
engine {
topology = "prespawn"
contexts { spawn = "auto"; reserve = 2; min = 1; max = 16 }
}
| Property | Meaning | Default |
|---|---|---|
topology | "prespawn", the only value. | "prespawn" |
contexts.spawn | Context count: a positive integer, or "auto" (physical cores minus reserve, clamped). | 1 |
contexts.reserve | Cores subtracted for "auto"; does not pin CPUs. | 2 |
contexts.min, contexts.max | Bounds for any count. | 1, none |
maxContexts | Deprecated fixed count; cannot combine with contexts. | — |
Each context evaluates the entry module once, with its own globals, before the server is ready.
--contexts=N|auto on run, serve and dev overrides spawn. More than one context requires Linux.
OpenTelemetry block
opentelemetry {
service { name = "checkout"; version = "1.4.2"; environment = "production" }
resource { ["cloud.region"] = "us-east-1" }
destinations {
["collector"] { endpoint = "http://localhost:4317"; protocol = "grpc" }
["datadog"] { provider = "datadog"; site = "us5" }
["sentry"] { provider = "sentry" }
}
traces { sampler = "parentbased_traceidratio"; ratio = 0.25 }
metrics { interval = 30.s }
logs { level = "info" }
runtime { logs = "warn" }
}
Telemetry is off until a destination exists here, in OTEL_*/ELIDE_OTEL_* variables, or in --otel-*
flags. Those override this block, flags first; see Runtime Environment Variables.
elide run, elide serve, elide test, elide build and elide install in a project read this block; elide run file.js
inside a project reads it when elide.pkl contains the word opentelemetry. See Configuration. Credentials are never written here: name the environment variable that holds them.
| Property | Meaning | Default |
|---|---|---|
enabled | false turns telemetry off, whatever the environment says. | — |
service.name, .version, .namespace, .environment | service.* and deployment. resource attributes. | unknown_service:elide |
resource | Extra resource attributes. | — |
destinations | Named places to send telemetry. | none |
traces.enabled, .sampler, .ratio, .propagators | Application spans. Samplers as OTEL_TRACES_SAMPLER. | on, parentbased_always_on, tracecontext + baggage |
metrics.enabled, .interval, .temporality | Application metrics. | on, 60.s, cumulative |
logs.enabled, .level, .console | Application logs; console exports console.*, Python logging and similar output. | on, info, on |
profiles.enabled, .frequency | Guest CPU profiles (experimental). | off, 100 per second |
runtime.traces, .metrics, .logs | Elide’s own spans, metrics, and log threshold. | on, on, warn |
propagation.baggage | W3C baggage on Elide’s HTTP server and clients; see Baggage. | off |
shutdownTimeout | Final export deadline at exit. | 5.s |
Each destination:
| Property | Meaning | Default |
|---|---|---|
provider | otlp, sentry, datadog, posthog, honeycomb, or grafana. | otlp |
endpoint | Base URL; replaces a provider’s host. /v1/<signal> is appended for HTTP. | http://localhost:4318 (4317 for gRPC) |
protocol | grpc, http/protobuf, or http/json. | http/protobuf |
headers, headerEnv | Literal headers, and headers read from named variables. | — |
credential | Variable holding the provider’s key: DD_API_KEY, POSTHOG_PROJECT_TOKEN, HONEYCOMB_API_KEY, GRAFANA_. | as listed |
dsn | Variable holding a Sentry DSN. | SENTRY_DSN |
site | Datadog site: us1, us3, us5, eu, ap1, ap2, gov, or a domain. | DD_SITE, then us1 |
region | us/eu (PostHog, Honeycomb), or a Grafana Cloud zone such as prod-us-east-0. | us |
signals | traces, metrics, logs, profiles. | what the provider accepts |
compression, timeout | Request compression and deadline. | gzip, 10.s |
perSignal | Per-signal endpoint, protocol, headers, headerEnv, compression, timeout. | — |
| Provider | Signals sent by default | Also accepted | Protocols |
|---|---|---|---|
otlp | traces, metrics, logs | profiles | all |
sentry | traces, logs | — | http/protobuf |
datadog | metrics (delta), logs | traces (agentless intake preview) | http/protobuf; http/json except logs |
posthog | logs | traces | http/protobuf |
honeycomb | traces, metrics, logs | — | all |
grafana | traces, metrics, logs | — | http/protobuf |
Errors are sent as exception log records and span events, plus the elide.errors metric, so every provider that
accepts logs, traces, or metrics receives them. See OpenTelemetry for usage and Providers for each provider. Asking a provider for a signal or protocol it does not accept is an error.
Baggage
Elide’s HTTP server and clients propagate traceparent and tracestate. They pass W3C baggage only when you turn a
direction on, because baggage arriving from a client is untrusted input:
opentelemetry {
propagation {
baggage {
inbound = true
outbound = true
allow { "tenant"; "region" }
spanAttributes { "tenant" }
}
}
}
| Property | Meaning | Default |
|---|---|---|
inbound | Served requests’ baggage headers become the handler’s baggage. | false |
outbound | Outgoing fetch and HTTP client requests carry the current baggage, unless the request sets baggage itself. | false |
allow | Keys allowed in both directions. | all keys |
spanAttributes | Inbound keys recorded on the server span as baggage.<key>; each must be in allow. | none |
A header over 8,192 bytes or 180 members, or with any malformed member, is dropped whole. Baggage received from a
client reaches outgoing requests only when both directions are on. Application code can always read, set and send
baggage through the OpenTelemetry API; OTEL_PROPAGATORS affects only that API.
Sources
sources {
["main"] = "lib/**/*.kt"
["integrationTest"] {
type = "test"
dependsOn { "main" }
paths { "it/**/*.kt" }
resources { "it/fixtures"; new { from = "it/config"; into = "META-INF" } }
}
}
| Property | Meaning | Empty or absent |
|---|---|---|
type | "source", "test", "example" or "other". | Inferred from the name. |
paths | Globs or directories. | src/<name>/<language>. |
resources | Paths, or new { from; into } roots. | src/<name>/resources. |
dependsOn | Source sets visible to this one. | Absent: test and example sets see main. Empty: nothing. |
See Source Sets.
Dependencies
dependencies {
maven {
packages { "com.google.guava:guava:33.5.0-jre" }
testPackages { "org.junit.jupiter:junit-jupiter:5.13.4" }
substitutions { ["com.google.guava:guava"] = "libs/guava-patched.jar" }
}
npm { packages { "react@19.0.0" }; devPackages { "typescript@5.6.2" } }
pypi { packages { "requests>=2" }; optionalPackages { ["dev"] { "pytest>=8" } } }
spring { version = "4.0.0"; starter { "web" }; testStarter { "test" } }
}
| Block | Properties |
|---|---|
maven | packages, devPackages, modules, compileOnly, runtimeOnly, processors, testPackages, kotlinPlugins, exclusions, resolutions, substitutions, repositories, enableDefaultRepositories, localRepository |
npm | packages, devPackages |
pypi | packages, optionalPackages (named groups); elide install does not install them. |
spring | version, starter, testStarter; expands into maven. |
| Value | Form |
|---|---|
| Maven entry | "group:artifact:version[:classifier]", a MavenPackageSpec (group, name, version, classifier or coordinate), a local JAR path, or a project reference. |
| Repository | A URL, or a spec with url, name, description, credentials (username, password, ntlmDomain, ntlmWorkstation). |
resolutions key | group:artifact; the value is an exact version overriding direct and transitive requests, without adding a dependency. See version resolutions. |
substitutions key | group:artifact (any version) or group:artifact:version; the value is a file path. |
A substitution keeps the coordinate’s transitive dependencies and puts the file on every classpath in its place. Paths resolve against the declaring manifest; members inherit the root’s. Order the task that generates the file first. Buckets and repositories: Dependencies.
JVM
jvm {
main = "example.Main"
target = 25
flags { "--add-opens=java.base/java.lang=ALL-UNNAMED" }
defs { ["app.env"] = "dev" }
java { release = 25; compiler { flags { "-Xlint:all" } } }
}
| Property | Meaning | Default |
|---|---|---|
main | Entrypoint class for elide run, JARs, applications and native images. | — |
target | Bytecode target: 8 … 29, 1.8, "latest", "stable" or "auto". | "auto" (21) |
javaHome | Java home for external compiles and forked JVMs. | Elide’s own |
preferBali | External JVM runs launch bali from PATH instead of java, or warn and use java. | false |
features.testing | JUnit dependencies on test sets. | true |
features.automodules | Automatic modules for JARs without a descriptor. | true |
features.graalvm | org.graalvm SDK APIs on the compile classpath. | false |
java.source, java.release | Source and --release levels; see Java Compiler. | "auto" |
java.compiler.mode | "embedded" or "external". | "embedded" |
java.compiler.flags | Extra javac flags. | none |
java.sourceSets | Per-source-set release and flags; see Java Compiler. | none |
java.bindings | Named C-header binding groups for jextract; see below. | none |
java. | Binding-group names compiled into that source set. | none |
flags | JVM flags for elide run, the test JVM and start scripts. | none |
defs | System properties (-D), applied wherever flags are. | none |
debug | Compile with -g. | true |
C header bindings
In 1.6.2, declare native bindings under jvm.java.bindings and select them for the Java source set that owns
their generated classes:
jvm {
java {
bindings {
["api"] {
headers { "native/api.h" }
packageName = "example.nativeapi"
headerClassName = "NativeApi"
includeDirs { "native/include" }
libraries { "answer" }
}
}
sourceSets {
["main"] { bindings { "api" } }
}
}
}
| Binding property | Contract | Default |
|---|---|---|
headers | Header paths or globs; unmatched globs fail. | required |
packageName | Java package for generated bindings. | required |
headerClassName | Generated header class name. | required |
includeDirs | Header search directories. | empty |
defines | Preprocessor definitions, such as API_VERSION=1. | empty |
libraries | Shared-library specifications used by generated lookup code. | empty |
useSystemLoadLibrary | Use system library loading for the declared libraries. | false |
Paths resolve against the owning project. A group has one owning source set; dependent sets use its classes through their normal dependencies. Declaring a group does not select it for compilation. These bindings require a distribution with native tools. See C header bindings for generation-only targets, exported sources, incremental inputs, and command-line selections, and jextract for native-library loading at runtime.
Kotlin
kotlin {
apiLevel = "auto"
languageLevel = "auto"
compilerOptions { allWarningsAsErrors = true; optIn { "kotlin.time.ExperimentalTime" } }
features { serialization = true; metro = false }
toolchain = "embedded"
plugins { ["org.jetbrains.kotlinx.serialization"] { ["mode"] = "json" } }
}
| Property | Meaning |
|---|---|
apiLevel, languageLevel | "auto", "latest", "stable", or "2.2" … "2.5". |
compilerOptions | optIn, progressiveMode, extraWarnings, allWarningsAsErrors, suppressWarnings, verbose, freeCompilerArgs, apiVersion, languageVersion, includeRuntime, noStdlib, javaParameters, jvmTarget, noJdk, jvmTargetValidationMode, incremental |
features | testing, kotlinx, defaultPlugins, serialization, coroutines, atomicfu, powerAssert, metro, compose, reflection. compose defaults to false and requires an explicit Compose runtime dependency. |
toolchain | "embedded", new Kotlin. or new Kotlin.. |
plugins | Options per compiler-plugin id, passed as -P plugin:<id>:<key>=. |
Defaults: Kotlin Compiler.
JavaScript
| Property | Meaning | Default |
|---|---|---|
javascript.ecma | Declared ECMAScript edition: a year 2015 … 2025, "stable" or "latest". elide project info shows it; it does not change which syntax runs or how code is built (JavaScript language). | "stable" |
Toolchain
toolchain { engines { ["elide"] = ">=1.6.0" } }
| Property | Meaning |
|---|---|
engines["elide"] | Version or semver range, or new { version = "…" }; a running Elide outside it fails validation. |
engines[<other>] | Accepted, not enforced. |
Dev
dev {
source { platform = "github"; project = "example/app" }
mcp {
registerElide = true
advice = true
resources { new { path = "docs/ARCHITECTURE.md"; name = "architecture" } }
}
}
| Property | Meaning | Default |
|---|---|---|
source.platform, source.project, source.subpath | Source host: "github", "gitlab", "bitbucket", "git" or another name. | — |
mcp.registerElide | Register Elide as an MCP tool. | true |
mcp.advice | Expose elide project advice as an MCP resource. | true |
mcp.resources | Extra MCP resources: path, name, description, mimeType (detected if omitted). | none |
server.host, server.port | Unused by elide dev, which takes --host/--port (default 127.0.0.1:3000). | "0.0.0.0", 8080 |
Web
| Property | Meaning | Default |
|---|---|---|
web.css.minify | Minify built CSS. | true |
web.css.targets | Browser targets: new { browser = "chrome"; version = "120" }. | none |
web.minifyHtml | Minify rendered HTML. | true |
web.browsers | Browser targets for all outputs; css.targets overrides it for CSS. | none |
See Web Toolchain.
Artifacts
import "elide:Jvm.pkl" as Jvm
artifacts {
["app"] = new Jvm.Jar {
name = "app.jar"
options { entrypoint = "example.Main" }
sources { "main" } // optional; empty packages every non-test source set
}
}
The key names the build task. Outputs go under .dev/artifacts/<kind>/.
| Type | Module | Fields |
|---|---|---|
Jar, SourceJar, JavadocJar, JvmApplication | elide:Jvm.pkl | JAR Assembly |
NativeImage | elide:NativeImage.pkl | Native Image |
WebImage | elide:NativeImage.pkl | WebImage |
ContainerImage | elide:Container.pkl | JVM Containers |
StaticSite | elide:Web.pkl | Static Sites |
| Common field | Meaning |
|---|---|
dependsOn | Artifact names to build first. |
name (JARs) | "app" and "app.jar" both give app.jar; a SourceJar gives app-sources.jar. |
WebImage
WebImage takes the NativeImage fields from, name, entrypoint,
moduleName, dependsOn and options, has no type, and adds:
| Property | Values | Default |
|---|---|---|
backend | "wasm-gc" (host GC) or "wasm-lm" (linear memory). | "wasm-gc" |
runtime | "generic", "browser" or "node". | "generic" |
autoRun | Start the program when the loader loads. | true |
sourceMap | Emit a JavaScript source map. | false |
entrypoint (or jvm.main) is required even with autoRun = false. Do not pass raw flags for these four settings.
Guide: WebImage; flag-based artifacts:
migration.
Publishing
publishing {
maven {
groupId = "dev.example"
artifactId = "example" // default: the project name
localRepository = "~/.m2/repository" // the default
artifacts { "lib"; "lib-sources" } // default: every Jar, SourceJar and JavadocJar
pom {
name = "Example"
description = "An example library." // default: the project description
url = "https://example.dev"
licenses { new { name = "Apache-2.0"; url = "https://www.apache.org/licenses/LICENSE-2.0" } }
developers { new { id = "jdoe"; name = "J. Doe" } }
scm { url = "https://github.com/example/example" }
}
repositories {
["internal"] = "https://repo.example.dev/releases" // or new Jvm.MavenRepositorySpec { url = … }
["central"] = new Publishing.CentralPortal {} // Maven Central; import "elide:Publishing.pkl" as Publishing
}
signing { gpg { keyName = "0123ABCD" } } // optional; omit keyName for gpg's default key
}
}
elide publish builds the selected JARs and installs them with a POM into the local Maven repository. The version is
the project’s version. A publication needs a groupId, a version and exactly one Jar. A SourceJar publishes
under its classifier (default sources), a JavadocJar under javadoc. A relative localRepository resolves
against the manifest that declares it.
| Manifest | Published POM |
|---|---|
packages, modules | compile dependencies |
runtimeOnly | runtime dependencies |
compileOnly, devPackages, processors, kotlinPlugins, testPackages | Omitted |
Versionless exclusions | An <exclusion> on every dependency |
| A sibling project | The sibling’s own publishing coordinates |
A Jar.from sibling | Its packages, modules and runtimeOnly, unless already listed |
| A local JAR path | An error; consumers cannot resolve it |
The POM also lists libraries Elide puts on a Kotlin project’s classpath without a declaration, as compile
dependencies, because consumers need them at run time: kotlin-stdlib and kotlin-reflect at the project’s Kotlin
version, and the runtimes kotlin.features turns on (kotlinx-coroutines-core, kotlinx-serialization, the Metro
runtime). These appear in the published POM even though elide.pkl doesn’t name them. Turn one off where it comes
from (kotlin.features, or kotlin.compilerOptions.noStdlib), or declare it yourself to pin a different version.
jvm.features.graalvm adds the GraalVM SDK at runtime scope.
elide publish --to <name> publishes to a repository from repositories instead, with .md5, .sha1, .sha256 and
.sha512 checksums for every file. Credentials come from ELIDE_MAVEN_<NAME>_USERNAME and
ELIDE_MAVEN_<NAME>_PASSWORD, where <NAME> is the repository name uppercased with every character other than a
letter or digit turned into _ (internal → ELIDE_MAVEN_INTERNAL_USERNAME, my-repo → ELIDE_MAVEN_MY_REPO_…),
and otherwise from the repository’s credentials. Two names that map to the same variables (my-repo and my_repo)
are refused. Plain http:// repositories other
than localhost are refused without --allow-http-repositories.
With signing set, a remote publish signs every file with the gpg binary (<file>.asc); signing {} signs with
gpg’s default key, and signing { gpg { keyName = "…" } } picks one. A local publish signs only with
--sign, and --no-sign turns signing off. gpg-agent asks for the passphrase. For CI, set ELIDE_GPG_PASSPHRASE and
Elide passes it to gpg through loopback pinentry. Elide never reads the key itself.
A CentralPortal repository publishes to Maven Central through the Central Publisher Portal. Create a user token in the
Portal and pass it as ELIDE_MAVEN_<NAME>_USERNAME and ELIDE_MAVEN_<NAME>_PASSWORD. Every project of the run goes
into one signed, checksummed bundle and one deployment, which the Portal validates and releases as a unit. Elide waits
until the Portal has validated it, and fails with the Portal’s errors if it does not pass. --no-wait returns right
after the upload instead.
CentralPortal property | Meaning | Default |
|---|---|---|
publishingType | USER_MANAGED: release the validated deployment in the Portal yourself. AUTOMATIC: release once validated. | USER_MANAGED |
url | Portal to upload to. | https:/ |
Before building, Elide checks what Central requires and reports everything missing at once: pom name,
description, url, licenses, developers and scm.url; a SourceJar and a JavadocJar artifact; signing (so
--no-sign is refused); and a version that is not a -SNAPSHOT.
In a workspace, members inherit the root’s publishing block except artifactId and artifacts, and a member’s own
settings win field by field. Repositories are inherited by name. A project that builds no JAR publishes nothing it
inherits.
To publish only some of a workspace’s projects, name them (elide publish core util) rather than changing their
publishing blocks, or pass --skip-existing to leave out every version already in the target; see
elide publish.
Testing
import "elide:Testing.pkl" as Testing
testing { reports { Testing.xmlReport() } }
| Property | Meaning |
|---|---|
testing.reports | Report formats for every runner, written to .; same as --reporter=junit. |
Coverage
import "elide:Coverage.pkl" as Coverage
coverage {
enabled = true
scope = "tests"
jvm {
excludes { "org.example.generated.*" }
reports { Coverage.xmlReport(); Coverage.htmlReport() }
}
js { paths { "src" } }
}
| Property | Meaning | Default |
|---|---|---|
coverage.enabled | Collect coverage without --coverage. | false |
coverage.scope | Tasks that collect: "tests", "runs" or "all". --coverage always covers the task it is passed to. | "tests" |
coverage.jvm.reports | JVM report formats: Coverage.htmlReport(), xmlReport(), csvReport(), written to .. | none |
coverage.jvm.excludes | Class-name patterns (*, ?) left uninstrumented, such as generated code. | none |
coverage.js.paths | JavaScript and TypeScript source roots to report, as LCOV in .. Empty reports the whole project. | none |
See Testing › Coverage.
Workspaces
workspace { members { "core"; "app" } }
Each member is a directory with its own elide.pkl; members cannot have members. elide init --template workspace
creates a root with a core library and an app that depends on it.
| Behavior | Rule |
|---|---|
| Build scope | From the root, elide build/elide test cover every project; from a member, only that member. |
| Cross-project tasks | elide build core:compile-kotlin-main, or elide build core for its default tasks. |
| Shared state | Resolved dependencies and build state live in the root .dev; outputs stay in each project’s .dev. |
| Version pins | A member can omit a Maven version and take the root’s; a conflicting version is an error. |
// core/elide.pkl
import "elide:Jvm.pkl" as Jvm
dependencies {
maven {
packages { "com.google.guava:guava" } // version from the root
}
}
artifacts {
["jar"] = new Jvm.Jar { name = "core" }
}
// app/elide.pkl
local core = project("core")
dependencies { maven { packages { core } } }
| Reference | Meaning |
|---|---|
project("core") | The project’s Jvm.Jar artifact and its compile classpath, built when needed. JVM sources alone do not count. |
project("core"). | Pick one JAR when the project declares several. |
project("core"). | Also see core’s Kotlin internal declarations, not its dependencies’. Only in packages, modules, compileOnly, testPackages. |
new Jvm. | Unpack core’s JAR into this one, building it first; no dependency needed. |
module.project("core") | Use in place, inside an object body; bare project(…) does not resolve there. |
new Artifacts. | Explicit form; import "elide:Artifacts.. |
A reference to a project with no JAR, or a misplaced friend(), fails when the build is configured.
Micronaut
See the Micronaut guide for complete build, test, and Native Image workflows.
Use the Micronaut Core version, not the platform BOM version. Core module names expand to
io.micronaut:micronaut-<name>:<version>; the matching micronaut-inject-java processor is installed
and used by Java compilation. Independently versioned modules, such as Micronaut Serialization,
remain ordinary Maven coordinates.
dependencies {
micronaut {
version = "4.10.23"
modules { "runtime"; "http-server-netty" }
testModules { "http-client" }
}
}
jvm {
micronaut {
config {
micronaut {
application { name = "example" }
server { port = 8080 }
}
custom {
enabled = true
origins = new Listing { "https://example.com" }
}
}
}
}
The optional jvm.micronaut.config accepts arbitrary JSON-compatible keys and values. Elide renders
it with Pkl’s JSON renderer and stages application.json on production classpaths and in JARs.
Elide adds the matching micronaut-jackson-core runtime dependency for the JSON configuration loader.
When supplying your own JSON resources, declare that loader yourself.
An authored application.json conflicts with this generated resource and fails the build; omit the
block to supply your own configuration through resources. Environment-specific files may still be
provided through resources. Changes to generated configuration invalidate resource and JAR tasks.
Direct io.micronaut:micronaut-* Core dependencies also select the matching processor after workspace
version pins are applied. Conflicting Core or processor versions fail validation. Satellite-module
versions and transitive-only framework dependencies do not select a processor: declare a Core module
or use the shorthand. This integration uses the existing Java annotation-processing path; it does not
enable KSP or Kotlin-source annotation processing in project builds.
Runnable examples are in
tools/smoketests/micronaut-pkl
and
tools/smoketests/micronaut-resources.
The sample guide includes run,
packaging, and smoke-test commands.
Test containers
testing.testcontainers describes disposable infrastructure shared by the project’s selected test runners.
Declare named entries in containers, each with an image, optional command and environment, exposed
TCP ports, and a wait strategy. environment on the outer block binds container connection values
into JavaScript/TypeScript and JVM test environments. startupTimeoutSeconds bounds total startup.
See Shared test containers for the complete configuration, readiness options, prerequisites, and lifecycle.