Skip to content

Adopt an existing project

Migrate a Java, Kotlin or Spring Boot project from Maven or Gradle to Elide with elide adopt: what it runs, its flags and exit codes, which projects it fits, and a worked example.

On this page

elide adopt starts an AI coding harness (Codex, Claude Code or OMP) in the current directory with a built-in migration prompt. The harness reads the build, edits files and runs Elide; Elide edits nothing itself. The prompt targets Java and Kotlin projects built with Maven or Gradle, especially Spring Boot, and tells the harness to keep any other languages working.

elide adopt

elide adopt migrates the build to elide.pkl. To keep Maven, Gradle or Bazel and use Elide’s compilers inside them, see Build tool integration.

Which projects it fits

ProjectFitWhy
Single-module Java or Kotlin app on Maven or GradleGoodDependencies, source layout, tests and JAR map onto elide.pkl. Tested.
Spring Boot application or serviceGoodThe prompt checks the main class, Spring dependencies and plugins, resources, tests and packaging. Tested.
A JVM build you want to keep, using Elide only to run and compileGoodChoose Existing build: no elide.pkl is required.
Multi-module buildsUntestedElide workspaces exist, but the prompt is not evaluated on them.
Heavy custom plugins, generated sources, unusual annotation processingPoorThe harness keeps Maven or Gradle for steps Elide does not replace; expect a partial migration.
AndroidUntestedThe prompt is not evaluated on Android builds.
JavaScript, TypeScript or Python onlyNot neededElide runs package.json scripts, pyproject.toml entry points and node:test files without a migration; see Project Setup.

Tested projects

These shapes pass elide install, elide build, elide test, startup and the original build, starting from a fresh checkout, with the Codex harness:

Project shapeExisting buildTested on
Java, Spring Boot applicationMavenSpring Petclinic: dependencies, resources, tests, runnable app, JAR
Java, Spring Boot serviceGradleSpring REST service: dependencies, resources, tests, HTTP readiness
Kotlin/JVM command-line appGradle Kotlin DSLSingle module with Kotlin serialization and coroutines

The Claude Code harness is shown on the Kotlin app in the worked example.

Before you start

  1. Install and sign in to a harness. Elide runs it from PATH:

    ChoiceExecutableHarness
    codexcodexOpenAI Codex CLI
    claudeclaudeClaude Code
    ompompOMP
  2. Commit the project, so the migration is one reviewable diff.

  3. Build it once with Maven or Gradle, so there is a known-good baseline.

  4. cd into the project, or pass -p DIR.

Run interactively

elide adopt asks three questions, then starts the harness. Flags answer a question in advance.

QuestionAnswersFlag
Use elide build with an elide.pkl project manifest?Yes (default): Elide build. No: Existing build--build elide, --build existing
Which AI coding harness should perform the migration?codex, claude, omp--harness
How should the harness approve tool calls?auto-approve, manual-approve, yolo--approval
elide adopt --build elide --harness claude

Esc on a question exits 0 without starting the harness. Ctrl+C stops the harness and exits 130.

Build strategy

StrategyThe prompt tells the harness to
Elide buildWrite elide.pkl: keep src/main/src/test without declaring source sets, keep dependency versions and scopes, set the Java target and release, define the JAR with its main class. Keep Maven or Gradle until a final elide install, elide build, elide test, elide run and the original build all pass.
Existing buildKeep Maven or Gradle as the build; use Elide’s runtime and tools only where they help; not create elide.pkl just for elide build.

Both end with a summary of changed files, the validation run, and anything left to do.

Approval mode

ModeCodexClaude CodeOMPUse for
auto-approve--approve-for-me--permission-mode auto--auto-approveA committed worktree you will review.
manual-approve(no flag)--permission-mode manual--approval-mode=always-askUnfamiliar or sensitive repositories.
yolo--dangerously-bypass-approvals-and-sandbox--permission-mode bypassPermissions--approval-mode=yoloDisposable environments without secrets.

With auto-approve or yolo, Elide runs the harness in batch mode (codex exec --skip-git-repo-check, claude --print, omp --print) and shows a progress line; --log also streams the harness output. With manual-approve, the harness runs interactively and its output is always shown.

Run without questions

elide adopt \
  --build elide \
  --harness codex \
  --approval auto-approve \
  --non-interactive

--non-interactive requires --build, --harness and --approval; a missing one exits 2. It refuses manual-approve. Without a terminal, elide adopt exits 1 unless --non-interactive and all three are given.

Add guidance

--prompt-append FILE adds a UTF-8 file to the end of the prompt under Additional adoption guidance:. Repeat it to add several, in order:

elide adopt --prompt-append ./adoption-guidance.md --prompt-append ./team-rules.md

Use it for facts the harness cannot infer: internal repositories, which build to keep, commands that must keep working.

Output and exit codes

The harness’s edits are the only output in the project. On the worked example that was a new elide.pkl and .gitignore entries for .dev/. Elide prints Adoption log: PATH before starting; the log is kept at .dev/logs/adopt-<timestamp>-<pid>.log in the project.

Exit codeMeaning
0The harness exited 0, or a question was cancelled.
1The harness failed (Error: claude exited unsuccessfully (exit status: 3)), could not start (Error: failed to launch codex: No such file or directory), a --prompt-append file is unreadable, or there is no terminal.
2A flag is missing or invalid.
130Interrupted with Ctrl+C.

Validate the migration

Exit 0 means the harness finished, not that the migration is correct. Review the diff: dependency versions, source and resource directories, entry point, tests and packaging. Then run:

elide install
elide build
elide test
elide run

Run the original Maven or Gradle build too, while it exists. If the result is wrong, revert, add guidance with --prompt-append, and run again.

Worked example

A single-module Kotlin command-line app built with Gradle Kotlin DSL: Kotlin 2.3.20, JVM 17, kotlinx-coroutines-core 1.10.2, kotlinx-serialization-json 1.9.0 and one kotlin("test") test. Committed, then:

elide adopt --build elide --harness claude --approval auto-approve --non-interactive
Adoption log: /path/to/project/.dev/logs/adopt-1767225600-973648.log
[3m 56s] ✓ Project adopted in 3m 56s

The harness added elide.pkl and a .gitignore, and changed nothing else. The manifest keeps the Gradle versions and moves the rest into Elide’s terms:

amends "elide:project.pkl"

import "elide:Jvm.pkl" as Jvm
import "elide:Kotlin.pkl" as Kotlin

name = "kotlinx-cli"
version = "1.0.0"

dependencies {
  maven {
    packages {
      "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2"
      "org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0"
      // Gradle mediates annotations to 23.0.0 (via coroutines); Elide's nearest-wins picks 13.0.
      "org.jetbrains:annotations:23.0.0"
    }
    testPackages {
      // Gradle's `kotlin("test")` with `useJUnitPlatform()` resolves to the JUnit 5 variant.
      "org.jetbrains.kotlin:kotlin-test-junit5:2.3.20"
      // The JUnit launcher; with `testing = false`, Elide does not bundle one.
      "org.junit.platform:junit-platform-console:1.10.1"
    }
  }
}

jvm {
  main = "dev.elide.samples.MainKt"
  target = 17
  features {
    // JUnit comes from testPackages above, as with Gradle's `kotlin("test")`; Elide's bundled JUnit is off.
    testing = false
  }
  java {
    source = 17
    release = 17
  }
}

kotlin {
  // Matches the Kotlin Gradle plugin version in build.gradle.kts.
  toolchain = new Kotlin.ManagedKotlinToolchain {
    version = "2.3.20"
  }
  compilerOptions {
    jvmTarget = 17
  }
  features {
    // KotlinX libraries are declared explicitly above, at the versions Gradle uses; only the
    // serialization compiler plugin (Gradle's `plugin.serialization`) is enabled.
    kotlinx = false
    serialization = true
    coroutines = false
    atomicfu = false
    powerAssert = false
    metro = false
    reflection = false
  }
}

artifacts {
  ["jar"] = new Jvm.Jar {
    name = "kotlinx-cli"
    main = "dev.elide.samples.MainKt"
  }
}

Validation from a clean .dev/:

$ elide install
[504ms] ✓ Resolved 25 Maven dependencies (476ms)
[505ms] ✓ Dependencies installed in 484ms
$ elide test
 1 pass
 0 skip
 0 fail
Ran one test across one file. (0.57s)
$ elide run
[ 16ms] ⇥ Dependencies ready (Up to date)
[ 16ms] ⇥ Kotlin main compilation skipped (Up to date)
[ 16ms] ⇥ Java main compilation skipped (Up to date)
[ 17ms] ⇥ Packaging jar 'jar' skipped (Up to date)
{"completed":["PARSE","EMIT"]}
[138ms] ✓ JVM jar application completed successfully (121ms)
[139ms] ✓ Build successful in 126ms

elide build produced .dev/artifacts/jar/kotlinx-cli/kotlinx-cli.jar, and gradle build still passed.

See also

Was this page helpful?