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. onUnload is called when the mod is programmatically removed (currently reserved for future unload support).

AetherNativeModContext

The context parameter passed to onLoad is your gateway to everything the mod kernel exposes:
Property / MethodTypeDescription
applicationApplicationThe Android Application instance for the Aether process.
modIdStringStable identifier for this entrypoint — "<package-name>:<entrypoint-class>".
packageRootFileRoot directory of the extension package on disk.
classLoaderClassLoaderThe DexClassLoader used to load this mod.
kernelAetherModKernelThe full mod kernel — services, operations, and components registries.
diagnosticLoggerAetherDiagnosticLoggerAether’s internal diagnostic logger.
registerService()methodConvenience method — registers a service in kernel.services.
intercept()methodConvenience method — registers an operation interceptor in kernel.operations.
registerComponent()methodConvenience method — registers a Compose component in kernel.components.

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
  • 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.