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. onUnload is called when the mod is programmatically removed (currently reserved for future unload support).
AetherNativeModContext
Thecontext parameter passed to onLoad is your gateway to everything the mod kernel exposes:
| Property / Method | Type | Description |
|---|---|---|
application | Application | The Android Application instance for the Aether process. |
modId | String | Stable identifier for this entrypoint — "<package-name>:<entrypoint-class>". |
packageRoot | File | Root directory of the extension package on disk. |
classLoader | ClassLoader | The DexClassLoader used to load this mod. |
kernel | AetherModKernel | The full mod kernel — services, operations, and components registries. |
diagnosticLogger | AetherDiagnosticLogger | Aether’s internal diagnostic logger. |
registerService() | method | Convenience method — registers a service in kernel.services. |
intercept() | method | Convenience method — registers an operation interceptor in kernel.operations. |
registerComponent() | method | Convenience method — registers a Compose component in kernel.components. |
DEX compilation requirements
Aether uses Android’sDexClassLoader to load Native Mod code. Keep these constraints in mind:
DexClassLoaderaccepts.dex,.apk, or jar/zip files containingclasses.dex.- A plain JVM
.classjar 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 underaether.native in package.json:
package.json
classpath— one or more.dex,.apk, or DEX-containing zip/jar paths relative to the package root.libraryPath— optional directories containing.sonative libraries.entrypoints— fully-qualified class names that implementAetherNativeMod. Multiple entrypoints in one package are all loaded.
Minimal example
MyNativeMod.kt
Native Mods load on process start. Installing, updating, removing, or
changing a Native Mod requires restarting Aether before the change takes
effect.