Skip to main content
Native Mods are Kotlin classes compiled to DEX that load directly into the Aether process. They provide the deepest level of extension capability — direct access to Android APIs, Jetpack Compose, and every Aether internal.

When to use Native Mods

Choose a Native Mod over a Script Mod when you need any of the following:
  • Register a new service implementation — replace or augment Aether’s built-in services through the priority-ordered service registry.
  • Wrap or replace Compose components with full Compose code — Script components use a declarative UI tree; Native components give you unrestricted Jetpack Compose.
  • Access Android platform APIs not exposed through host methods — Context, PackageManager, platform sensors, etc.
  • Performance-critical operations that benefit from compiled, optimized Kotlin running directly in the app process.
  • Wildcard operation interception ("*") — intercept every operation dispatched through the mod kernel.

The AetherNativeMod interface

Every Native Mod entry class implements this interface:
onLoad is called once when the mod is loaded at process startup. When Aether explicitly shuts down the Native Mod manager, it calls onUnload in reverse load order and removes registrations owned by the mod. Abrupt process termination cannot run unload callbacks.

AetherNativeModContext

The context parameter passed to onLoad is your gateway to everything the mod kernel exposes:

Native tool titles

Native Mods can provide user-facing titles displayed on tool cards while a registered Pi tool is running and after it completes. Tool name matching is case-insensitive. Higher priority values win when multiple mods register titles for the same tool.
The returned cleanup function removes the title mapping. Non-blank titles are required.

DEX compilation requirements

Aether uses Android’s DexClassLoader to load Native Mod code. Keep these constraints in mind:
  • DexClassLoader accepts .dex, .apk, or jar/zip files containing classes.dex.
  • A plain JVM .class jar is not sufficient — run Android D8 or R8 on your compiled output to produce a DEX artifact.
  • Compose renderers must be compiled with a Compose compiler version compatible with the target Aether build.
  • Rebuild native mods when Aether implementation classes or the Kotlin/Compose toolchain changes. This coupling is intentional and analogous to version-specific Minecraft mods.

Classpath format in package.json

Declare your DEX artifact, optional native library directories, and entry class names under aether.native in package.json:
package.json
  • api — Native API compatibility. The current version is 1; version ranges are also accepted.
  • classpath — one or more .dex, .apk, or DEX-containing zip/jar paths relative to the package root.
  • libraryPath — optional directories containing .so native libraries.
  • entrypoints — fully-qualified class names that implement AetherNativeMod. Multiple entrypoints in one package are all loaded.

Minimal example

MyNativeMod.kt
Native Mods are the unrestricted tier. They can use reflection, JNI, and access Aether implementation classes directly. There is no permission sandbox. Install only Native Mods you trust completely.
Native Mods load on process start. Installing, updating, removing, or changing a Native Mod requires restarting Aether before the change takes effect.