# Native Image

> Compile a JVM application to a native executable or shared library with `elide native-image` or an Elide project artifact, or compile it to WebAssembly.

Native Image compiles a JVM application ahead of time to a standalone executable or shared library.

## Compile from the command line

```bash
elide native-image -- -cp app.jar com.example.Main
```

Compiler arguments go after `--`; `elide native-image -- --help` lists them. Reflection, resources, JNI and proxies
need reachability metadata. The final link needs a C toolchain on the host.

## Project artifact

```pkl
amends "elide:project.pkl"
import "elide:Jvm.pkl" as Jvm
import "elide:NativeImage.pkl" as Native

artifacts {
  ["app-jar"] = new Jvm.Jar {
    sources { "main" }
  }
  ["app"] = new Native.NativeImage {
    from { "app-jar" }
    entrypoint = "com.example.Main"
    type = "binary"
    options {
      optimization = "2"
      flags { "-H:+ReportExceptionStackTraces" }
    }
  }
}
```

| Property | Meaning | Default |
| --- | --- | --- |
| `from` | JAR artifact keys (not paths); empty means every declared JAR, or a JAR of the project's classes. | none |
| `name` | Output file name. | the project name |
| `entrypoint` | Main class. | `jvm.main` |
| `moduleName` | Launch module for modular JARs; see below. | module holding the entrypoint |
| `type` | `"binary"` (executable) or `"library"` (shared library). | `"binary"` |
| `options` | Compiler options; see below. | — |
| `dependsOn` | Artifacts to build first. | none |

Output goes to `.dev/artifacts/native-image/`, with the final arguments in `native-image.args`.

### Compiler options

| `options` property | Meaning | Default |
| --- | --- | --- |
| `optimization` | `"auto"`, `"b"` (quick build), `"s"`, `"0"` … `"4"`. | `"auto"` |
| `driverMode` | `"embedded"` (Elide's compiler) or `"external"` (`native-image` from `GRAALVM_HOME`/`JAVA_HOME`). | `"embedded"` |
| `verbose` | Verbose compiler output. | `false` |
| `linkAtBuildTime.enabled` | Link everything at build time. | `true` |
| `linkAtBuildTime.packages` | Packages to link at build time when `enabled` is `false`. | none |
| `classInit.default` | Default class initialization: `"buildtime"` or `"runtime"`. | `"buildtime"` |
| `classInit.buildtime`, `classInit.runtime` | Classes or packages initialized at build or run time. | none |
| `exclusions.all` | Coordinates kept off both paths. | the compiler's own JARs |
| `exclusions.classpath`, `exclusions.modulepath` | Coordinates kept off one path. | none |
| `pgo.enabled` | Apply profiles when present. | `true` |
| `pgo.profiles` | Profile files. | none |
| `pgo.instrument` | Build an instrumented image that records profiles. | `false` |
| `pgo.sampling` | Use sampling profiles. | `false` |
| `pgo.autoprofile` | Auto-profile features. | `false` |
| `features` | Compiler feature classes to enable. | none |
| `flags` | Extra `native-image` flags; a changed file named in a flag triggers a rebuild. | none |
| `cflags`, `ldflags` | Extra C compiler and linker flags. | none |
| `defs` | System properties for the image build. | none |

The top-level `nativeImage { }` block accepts the same options but does not apply them; set each artifact's `options`.

### Modular applications

If a JAR in `from` has a `module-info.class`:

- Modular JARs and the `dependencies.maven.modules` bucket go on `--module-path` with
  `--add-modules=ALL-MODULE-PATH`; everything else stays on the class path.
- The binary launches with `--module <module>/<entrypoint>`, using `moduleName` or the module holding the entrypoint.
- An entrypoint outside any module builds from the class path.

`moduleName` has no effect without modular JARs.

## Compile to WebAssembly

Declare a `WebImage` artifact or pass `--tool:wasm-gc` / `--tool:wasm-lm`; see [WebImage](https://elide.help/docs/toolchain/jvm/webimage).
To run existing WASM, see [WebAssembly](https://elide.help/docs/wasm). A native image can be the input to a
[container image](https://elide.help/docs/toolchain/jvm/containers).
