Elide Projects

Elide is capable of creating and managing Elide-native projects through a project toolchain.

An Elide Project consists of:

  1. Project manifest - elide.pkl is a powerful configurable Pkl-based manifest.
  2. Work directory - .dev acts as an internal directory, that Elide uses to store output and intermediate states of build tasks.
  3. Lockfile - .dev/elide.build.bin and .dev/elide.lock.v2.bin are read-only binary files used by Elide tooling. Generally, users shouldn't edit them.

Project CLI

There are three CLI commands that can depend on an Elide project to work, which they can access in two ways:

  1. Direct passing - by passing --project PATH you can specify the manifest that will be loaded for this command.
  2. Auto-detection - if no path is provided, the command will attempt to find a project manifest in the current directory.

As such a plain call of,

shell
 elide build

will attempt to search for manifest in a local directory, while

shell
 elide build -p PATH

will try to fetch the manifest from the path.

These are the commands that require a project.
CommandDescription
buildInstalls dependencies and compiles sources.
installInstall dependencies.
classpathGenerates a classpath for the project.

Building a Project

elide build is the main way to build projects. It generates a task graph based on the manifest configuration.

It's possible to view a full list of tasks that a build command generates from the project manifest.

shell
 elide build --inspect

To run a specific task,

shell
 elide build TASK

For example,

shell
 elide build compile-java-main

Elide Project Manifest

elide.pkl is a Pkl-based manifest that allows for extensive configuration of Elide project. For a field-by-field schema reference, see elide.pkl Reference.

The project manifest has a regimented, yet flexible structure.

pkl
# Importing project schema
amends "elide:project.pkl" 

# Importing configuration-specific schema
import "elide:Sources.pkl" as Src

# Project metadata
name = "project"
version = "1.0.0"
description = "example project"

# Project configuration
sources {
  ["main"] = new Src.SourceSetSpec {
    paths {
      "src/main/java<<>>*.java"
    }
  }
}

Project Metadata

Top-level declarations for project organization and housekeeping.
FieldTypeDefaultDescription
nameStringEmptyName of the project.
versionStringEmptyProject version number.
descriptionStringEmptyDescription of the project.

Build Context

Elide automatically populates two read-only (fixed) properties in every manifest at evaluation time. These expose the current Elide runtime version and manifest format version so that manifests can adapt their configuration conditionally.
PropertyTypeDescription
elideElideInfoInformation about the Elide runtime executing the build.
buildBuildInfoState captured from the Elide build system at evaluation time.
ElideInfo
FieldTypeDescription
versionsemver.VersionSemantic version of the Elide runtime executing the build.
channelReleaseChannelRelease channel of the runtime, either "release" or "debug".
BuildInfo
FieldTypeDescription
manifestVersionIntMajor version of the project manifest format. Incremented on breaking schema changes.
Because elide.version is a semver.Version, you can use Pkl's semver comparison methods to write version-gated configuration:
pkl
amends "elide:project.pkl"
import "pkl:semver"
import "elide:Sources.pkl" as src

sources {
  when (elide.version.isGreaterThan(semver.Version("1.1.0"))) {
    ["main"] = new src.SourceSetSpec {
      paths {
        "src/main/kotlin<<>>*.kt"
      }
    }
  }
}

Similarly, elide.channel lets you gate configuration on the release channel:

pkl
when (elide.channel == "release") {
  // release-only settings
}

Sources

For Elide project to build, sources have to be specified in the manifest. A general template of declaring sources is

pkl
import "elide:Sources.pkl" as Src
sources {
  ["main"] = new Src.SourceSetSpec {
    paths {
      "src/main/java<<>>*.java"
    }
  }
}

The import allows you to use source schema and helps Elide to parse the source section of the manifest.

Sources themselves are declared by paths, which are a list of pattern-matched paths.

Within the sources section, sources are grouped into named sets (such as ["main"] in this example). A set's name can be any string; its type defaults to source. Elide recognizes four source-set types. Currently only test changes build behavior (it is compiled with test dependencies and run as tests); source, example, and other are treated the same as source.
TypeDescription
sourceProduction sources (the default type).
testTest sources.
exampleExample sources.
otherOther sources.
Besides type, each source set accepts paths, the list of source paths or globs. JVM source sets can use Jvm.JvmSourceSetSpec, which adds resources as a map of mount-path to source-path for non-code files bundled with the set. See elide.pkl Reference for the complete source-set shape.

Test source sets are compiled with test dependencies and run by elide test. JVM test coverage is configured under testing { coverage { jvm { … } } }, which can emit HTML, XML, and CSV reports.

Entrypoint

Specifying an entrypoint allows Elide to automatically detect scripts to run.

pkl
entrypoint {
  "some.entry"
}

As such if during elide run no script was specified, Elide will attempt to fetch an entrypoint filepath from the manifest.

Scripts

Scripts are key value pairs, intended to work similar to scripts of Node's package.json.

Declared scripts are listed by elide project (and surfaced in elide project advice).

For example, if you specify in script

pkl
scripts {
  ["help"] = "elide --help"
}

Note: elide run does not currently execute a script by name — the first non-option argument to elide run is always resolved as a source file path. Running a script by its manifest name is not yet supported.

Dependencies

Elide comes with a built-in, polyglot dependency manager. A single dependencies { } block declares packages across three ecosystems — npm (JavaScript/TypeScript), PyPI (Python), and Maven (JVM) — and one elide install resolves and installs them all. See Dependencies for the full installer guide.

pkl
import "elide:Jvm.pkl" as Jvm

dependencies {
  npm {
    packages { "react@19.0.0" }
  }
  pypi {
    packages { "six==1.17.0" }
  }
  maven {
    packages { "com.google.guava:guava:33.4.8-jre" }
  }
}
npm and pypi each accept packages (and npm also devPackages); use their native specifier syntax (name@version for npm, name==version / name>=version for PyPI). The Maven block is the richest — the rest of this section covers it in detail. Elide can act as a Maven installer.

There are three ways to declare a Maven dependency:

pkl
import "elide:Jvm.pkl" as Jvm  

dependencies {
  maven {
    packages {
      // Coordinate string — the most common form
      "com.google.guava:guava:33.4.8-jre",
      // Structural form — use when you need to set a classifier or other fields
      new Jvm.MavenPackageSpec {
        group = "com.google.guava"
        name = "guava"
        version = "33.4.8-jre"
      }
      // Local JAR path — bypasses Maven resolution entirely (see below)
      "./libs/my-library.jar"
    }
  }
}

Maven dependencies are installed in your local Maven repository and linked into your project through .dev file.

Spring Boot starters

Spring Boot starters all share the coordinate shape org.springframework.boot:spring-boot-starter-, so a spring { } block lets you declare just the name and the Boot version:

pkl
dependencies {
  spring {
    version = "3.5.0"

    starter {
      "actuator"
      "web"
    }

    testStarter {
      "test"
    }
  }
}
starter entries resolve into packages (compile scope); testStarter entries resolve into testPackages. The example above is exactly equivalent to:
pkl
dependencies {
  maven {
    packages {
      "org.springframework.boot:spring-boot-starter-actuator:3.5.0"
      "org.springframework.boot:spring-boot-starter-web:3.5.0"
    }
    testPackages {
      "org.springframework.boot:spring-boot-starter-test:3.5.0"
    }
  }
}
version is the Spring Boot version — Spring Framework versions independently, and starters are versioned by Boot.

Only artifacts that follow the starter convention can be declared this way. Anything else — spring-boot-devtools, or artifacts in the org.springframework group — is declared as an ordinary coordinate in maven, and the two blocks merge:

pkl
dependencies {
  spring {
    version = "3.5.0"
    starter { "web" }
  }
  maven {
    packages {
      "org.springframework.boot:spring-boot-devtools:3.5.0"
      "org.springframework:spring-core:6.2.0"
    }
  }
}

Local JAR dependencies

Any dependency bucket (packages, modules, compileOnly, runtimeOnly, processors, kotlinPlugins, testPackages) accepts a local JAR file path in place of Maven coordinates. Path-based entries are read directly from disk.

pkl
import "elide:Jvm.pkl" as Jvm

dependencies {
  maven {
    packages {
      // Shorthand: any string that isn't a coordinate is treated as a path
      "./libs/my-library.jar"
      // Local JAR dependencies are declared as path strings (structural MavenPackageSpec entries are for coordinates only)
    }
    // Local JARs work in every bucket
    compileOnly {
      "./libs/annotation-processor.jar"
    }
    testPackages {
      "./libs/test-helpers.jar"
    }
  }
}

Relative paths are resolved from the project directory (the directory containing elide.pkl). Absolute paths are used as-is.

Elide Maven dependency manager recognizes multiple types of dependencies that serve different purposes in Elide.
TypeDescription
packagesDependencies used in the compilation and runtime classpaths.
modulesDependencies added to the compilation and runtime modulepath for use with Java modules.
testPackagesDependencies added to the compilation and runtime classpaths of test sources.
compileOnlyDependencies added only to the compilation classpath only.
runtimeOnlyDependencies used only at runtime, but not present during compilation.
processorsDependencies containing annotation processors.
kotlinPluginsDependencies containing Kotlin compiler plugins.
exclusionsMaven packages that should be excluded from the graph, e.g. to fix version conflicts manually.
devPackagesInstalled by elide install, but not added anywhere else, useful if you want to have things like JUnit installed for use as part of custom workflows, but not add it to your actual classpath.
repositoriesConfigurations for additional remote maven repositories.
It's possible to specify Maven repositories from which to pull packages.
pkl
import "elide:Jvm.pkl" as Jvm 

dependencies {
  maven {
    repositories {
      ["central"] = new Jvm.MavenRepositorySpec {
        name = "Maven Central"
        description = "The central Maven repository"
        url = "https:<<>>
      }
      ["google"] = "https://maven.google.com"
    }
  }
}

Or specify a local repository and connect to maven central

pkl
dependencies {
  maven {
    localRepository = ".m2/repository"
  }
}
Full list of configurations
TypeDescription
enableDefaultRepositoriesWhether to enable default repositories like Maven Central. Defaults to true.
| localRepository | Path to local maven repository | |repositories | A suite of extra Maven repositories. Each repository accepts a url plus optional credentials (username / password) for authenticated registries. |

The complete dependency schema, including npm and PyPI fields, is listed in elide.pkl Reference.

JVM

Elide has a mechanism that allows for high level of configuration of how Elide interacts with the JVM.

In order to start configuring the JVM, you have to import the JVM-specific schema.

pkl
import "elide:Jvm.pkl" as Jvm
jvm {
  # your configuration here
}

At the high-level, you can specify what JVM you want elide to target and specify and entry point for your JVM.

pkl
jvm {
  main = "test.class"
  target = "latest"
  javaHome = "home"
}
Full list of high-level configurations for the JVM.
ConfigurationDescription
mainEntrypoint of JVM.
targetJVM target level. Use a numeric level (e.g. 21) or "auto"; symbolic values such as "latest"/"stable" are passed to javac verbatim and rejected.
javaHomeSet a custom Java Home override.
featuresControls features and settings related to JVM support.
javaJava language settings.
flagsRuntime JVM flags.
features have two flags declared for JVM support, but they are not currently consumed by the build — automatic test dependencies are gated by kotlin.features.testing instead:
FeatureDescription
testingIf Elide needs to automatically provide test dependencies for JVM projects. (Boolean)
automodulesWhether auto-modules are enabled (JDK 9+ modulepath handling). (Boolean)
java controls settings relating to the Java language such as compiler configuration.
FeatureDescription
sourceThe source version to use.
releaseThe release version to use.
compilerControls settings relating to the Java compiler. Has two flags, mode which is used to configure what compiler to use and flags that control what flags to pass into compiler. Learn more about Elide compiler here
flags are a set of JVM-tuning flags.

Kotlin

Elide allows to configure Kotlin behavior.

pkl
kotlin {
  # your configuration here
}
Full list of high-level configurations of Kotlin.
ConfigurationDescription
apiLevelKotlin API level (display/metadata only — the effective compiler knob is compilerOptions.apiVersion).
languageLevelKotlin language level (display/metadata only — use compilerOptions.languageVersion).
compilerOptionsSpecifies options which relate to the Kotlin compiler.
featuresSpecifies Kotlin-related features and options within Elide.
toolchainDescribes a Kotlin toolchain to be used for compilation.
pluginsOption key-value pairs to configure a Kotlin compiler plugin. (Declared but not currently consumed — compiler plugins are enabled via kotlin.features and dependencies.maven.kotlinPlugins.)
compilerOptions
OptionDescription
optInOpt-ins to add to Kotlin compiler invocations.
progressiveModeWhether to enable the compiler's progressive mode.
extraWarningsWhether to enable extra K2 warnings and checks.
allWarningsAsErrorsReport an error if there are any warnings.
suppressWarningsDon't generate any warnings.
verboseEnable verbose logging output.
freeCompilerArgsArbitrary arguments to pass to the Kotlin compiler.
apiVersionExplicitly set an API version for Kotlin Compiler invocations; this should typically be left at the default, which allows Elide to align API version options.
languageVersionExplicitly set a language version for Kotlin Compiler invocations; this should typically be left at the default, which allows Elide to align language version options.
includeRuntimeInclude Kotlin runtime classes within the output artifact.
noStdlibDon't automatically include the Kotlin Standard Library on the classpath.
javaParametersGenerate metadata for Java 1.8 reflection on method parameters.
jvmTargetExplicitly set a JVM target; typically this should be left at the default, which allows Elide to align JVM target options with Java, as applicable.
noJdkDon't automatically include the Java runtime on the classpath.
jvmTargetValidationModeValidation of JVM target compatibility between Kotlin and Java.
incrementalEnable incremental compilation for Kotlin sources. Enabled by default.
features
FeatureDescription
testingWhether to enable Kotlin's test support features.
kotlinxWhether to enable KotlinX dependencies automatically on the classpath.
defaultPluginsWhether to enable the default suite of built-in plugins for the Kotlin compiler.
serializationEnable or disable KotlinX serialization support.
coroutinesEnable or disable KotlinX Coroutines support.
reflectionWhether to enable Kotlin's reflection features. (Declared but not currently consumed by the build.)
toolchain
ConfigurationDescription
versionDescribes a managed Kotlin toolchain using a specific version. Managed toolchains are automatically resolved and downloaded by Elide when required.
pathPath to a local Kotlin distribution.
To specify a plugin to modify, you have to access it as a map. The plugin options are also set as key-value pairs.
pkl
plugins {
  ["plugin"] = {
    ["setting"] = "value",
  }
}

JavaScript

Elide allows to configure JavaScript ECMA level for the project.

pkl
javascript {
  ecma = "latest"
}

Native Image

Elide accepts a project-wide nativeImage { } block. Note: this block is currently parsed but not applied by the build — set Native Image options per artifact, in the artifact's options { } block (see the Native Image artifact below). The schema below documents the block's shape.

In order to start configuring the native compiler, you have to import a specific schema.

pkl
import "elide:NativeImage.pkl" as NativeImage

nativeImage {
  # your configuration here
}
Full list of high-level configurations of native compiler.
ConfigurationDescription
verboseWhether to activate verbose output.
linkAtBuildTimeBuild-time linkage options.
classInitClass initialization options.
exclusionsExclusions to apply to classpath and modulepath calculations.
optimizationOptimization level for the Native Image ("auto", "b", "s", "0"-"4").
pgoPGO (Profiling Guided Optimization) settings.
driverModeWhether to invoke Native Image internally ("embedded"), or as a sub-process ("external").
flagsExtra flags to pass to the Native Image compiler; added to all project targets.
cflagsExtra flags to pass to the native C compiler; added to all project targets.
ldflagsExtra flags to pass to the native linker; added to all project targets.
defsDefinitions of system properties to pass during the Native Image build.
featuresEnabled compiler features.
linkAtBuildTime
OptionDescription
enabledWhether link-at-build-time is enabled as the default.
packagesSpecific packages to link at build time.
classInit
OptionDescription
defaultWhether initialize-at-build-time is enabled as the default (default: "buildtime" or "runtime").
buildtimeSpecific classes or packages to initialize at build time.
runtimeSpecific classes or packages to initialize at runtime.
exclusions
OptionDescription
allExclusions from all paths. (default list: "org.graalvm.compiler:compiler", "org.graalvm.espresso:espresso-svm", "org.graalvm.nativeimage:native-image-base", "org.graalvm.nativeimage:objectfile", "org.graalvm.nativeimage:pointsto", "org.graalvm.nativeimage:svm")
classpathClasspath exclusions to apply.
modulepathModulepath exclusions to apply.
pgo
OptionDescription
enabledWhether PGO is enabled (only activates with present profiles).
autoprofileWhether to enable auto-build features for PGO. (Declared but not currently consumed.)
instrumentWhether to instrument for PGO.
samplingWhether to use sampling for PGO.
profilesPGO profiles to apply.

Engine

This configuration is responsible for configuration of the execution engine used by Elide when running a project.

pkl
engine {
  # your configuration here
}
ConfigurationDescription
maxContextsIntended maximum number of guest contexts. (Declared but not currently consumed by the runtime.)

Dev

Dev configurations allow Elide to integrate fully into a development process of a project.

In order to start configuring dev settings, you have to import a specific schema.

pkl
import "elide:Dev.pkl" as Dev

dev {
  # dev configuration here
}
High level dev definitions
ConfigurationDescription
sourceProject source configuration. (Declared but not currently consumed by the build.)
mcpSettings which apply to Model Context Protocol (MCP) servers.
serverDevelopment server settings. (Declared but not currently consumed — the dev server reads host/port from the CLI.)
source
ConfigurationDescription
platformPlatform which holds this project's source ("git", "github", "gitlab", "bitbucket", any).
projectProject name or path.
subpathSubpath for this project, as applicable.
mcp
ConfigurationDescription
resourcesAdditional MCP resources. (Declared but not currently consumed — only registerElide and advice are honored.)
registerElideWhether to register Elide as an MCP tool.
adviceWhether to register project advice with MCP.
To declare an MCP resource, use the following pattern:
pkl
resources {
      new Dev.McpResource {
        # some resource config
      }
    }
MCP resources have extensive config list.
ConfigurationDescription
pathPath to the file.
nameResource name.
descriptionResource description.
mimeTypeMime type to explicitly set; one is detected if not provided.
server
ConfigurationDescription
hostHost to listen on.
portPort to listen on.

Toolchain

Toolchain settings let you configure which Elide engine version to use.

pkl
toolchain {
  engines {
    ["elide"] = ">1.0.0"
  }
}

Artifacts

Elide can produce a variety of artifacts that can be placed into your project. These are declared as key-value pairs inside artifact configuration.

pkl
artifacts {
  ["some-artifact"] = {
    # some artifact
  }
}
There are six types of artifacts.
TypeDescription
Jvm.JarDescribes a JAR output artifact.
Jvm.SourceJarDescribes a sources JAR artifact that packages source files.
Jvm.JavadocJarDescribes a Javadoc JAR artifact that generates and packages documentation.
NativeImage.NativeImageDescribes a Native Image artifact within an Elide project.
Web.StaticSiteDeclares a static website as an artifact.
Container.ContainerImageDescribes a container image built from JVM or native output (see Containers).
To use a specific artifact type, you have to import its parent schema. For example, to use Jvm.Jar,
pkl
import "elide:Jvm.pkl" as Jvm

artifacts {
  ["some-jar"] = new Jvm.Jar {
    # some config here
  }
}
Note:

When you want to use a source in an artifact, you have to use them by name that are already declared by in project metadata. For example, you can use main in artifact sources, if they are declared in metadata.

Jvm.Jar
ConfigurationDescription
nameFilename for the resulting JAR.
sourcesWhich source set to build this JAR from.
resourcesWhich resources to add to the JAR (key-value pair of name to path).
manifestKeys and values to include in the JAR's manifest.
manifestFileManifest file path.
excludesPatterns to exclude.
optionsOptions for the JAR.
option
OptionDescription
compressWhether to apply compression.
defaultManifestPropertiesWhether to add default manifest properties.
entrypointMain entrypoint for the JAR, if applicable.

Jvm.SourceJar
ConfigurationDescription
sourcesWhich source set to build this JAR from.
classifierClassifier for the JAR.
excludesPatterns to exclude from the sources JAR.
includesPatterns to include in the sources JAR.

Jvm.JavadocJar
ConfigurationDescription
sourcesWhich source set to build this JAR from.

NativeImage.NativeImage
ConfigurationDescription
fromArtifacts from which to build the Native Image.
nameName of the output artifact (binary or library); computed if omitted.
entrypointEntrypoint class for the Native Image.
typeType of image to produce: binary or library.
moduleNameJPMS module of the entrypoint class. (Declared but not currently consumed — the entrypoint is taken from entrypoint / jvm.main.)
optionsNative Image compiler options for this artifact.

Web.StaticSite
ConfigurationDescription
srcsPath to the root source directory for the site.
domainProduction domain for this site. (Declared but not currently consumed by the build.)
previewPreview domain for this site. (Declared but not currently consumed by the build.)
prefixWeb prefix where this site is mounted; considered for links and assets. Must end with a slash.
assetsPublic web path for assets. (Declared but not currently consumed by the build.)
stylesheetsStylesheets to add to all pages.
scriptsScripts to add to all pages.
rewriteLinksRewrite links when rendering markdown documents.
hostingStatic site host. (Declared but not currently consumed by the build.)

Web

This configuration describes settings which apply in web-based environments; these settings configure how Elide builds and serves web applications, and related resources like images, stylesheets, and JavaScript.
ConfigurationDescription
cssSettings to apply to CSS processing and serving.
minifyHtmlWhether to minify generated HTML (default true).
browsersBrowser support. (Not currently consumed — CSS targeting uses css.targets.)
css
ConfigurationDescription
minifyWhether to enable minification of CSS code.
targetsTarget platforms (browsers) to consider when rendering/building CSS.
To create a new CSS target, you have to import parent schema.
pkl
import "elide:Web.pkl" as Web

web {
  css {
    targets {
        new Web.CssTarget {
          # some config
        }
    }
  }
}
target
ConfigurationDescription
browserThe name of the browser type to target("chrome", "firefox", "safari", "edge", "opera", String).
versionThe version of the browser to target.

Elide Lockfile

Elide lockfile contains information about project metadata as well as a resolved dependency graph. It allows for faster elide build as unmodified dependency list will be skipped and resolved dependency graph will be used

Do not modify the lockfile as it may result in failed builds.