Skip to main content
Aether’s Mod Kernel lets you build extensions that deeply integrate with the app — from adding new agent tools to replacing built-in UI components or accessing Android APIs directly. A single extension package can span all three tiers simultaneously, sharing code and configuration across Pi agent logic, hot-reloadable UI surfaces, and full-native Kotlin modules.

Three extension tiers

Each tier targets a different layer of the Aether stack with a different language, loading model, and access surface. The pi.extensions tier integrates with the Pi Coding Agent layer — register commands, tools, and hooks that the agent executes. The aether.extensions tier gives you the Script Mod API v2: register UI surfaces, replace or wrap built-in Compose components, define full-screen pages, read and write app state, invoke services, and intercept operations. The aether.native tier loads compiled Kotlin DEX code directly into the app process, with unrestricted access to every Android API, Compose composable, and Aether implementation class.

No permission sandbox

Extensions are trusted code. There is intentionally no permission sandbox. Installing an extension means trusting it with the Node.js runtime, the Android application context, all Aether services, and the Alpine/Termux workspace. Native Mods can use reflection, JNI, or Android APIs directly. The public registration APIs are convenience and interoperability surfaces, not security boundaries. Only install extensions from sources you trust.

One package, multiple tiers

A single package.json can declare all three tiers at once. The pi.extensions array, aether.extensions array, and aether.native object are independent fields — you can include any combination, point them to separate entry files, or share a single entry file across pi.extensions and aether.extensions using named exports. This lets you ship a combined package that behaves correctly in both the Pi Coding Agent and the Aether Android app.

Installing extensions

Imported extension packages live under ~/.aether/extensions inside Aether’s managed Alpine filesystem. You can install an extension in two ways:
  • Import a zip: open Settings → Extensions, tap Import extension, and select the zip file. Aether installs runtime npm dependencies when needed, then replaces the installed copy and loads it immediately. A failed install or reload restores the previous copy.
  • npm packages: add the package through Aether’s package management interface and declare aether.extensions or aether.native entries in its package.json. Aether discovers Script and Native entrypoints alongside locally installed extensions.

Hot reload

Script Mod entry directories are watched automatically. Reloads are serialized and atomic: Aether loads every new Script factory before replacing the active runtime. If loading fails, the previous working runtime remains active and the error appears in Settings → Extensions. Native Mods are discovered and loaded only during app process startup; installing, updating, removing, or changing a Native Mod requires restarting Aether.

Explore further

Package Format

Learn the package.json structure for all three tiers with field-level reference and examples.

Quickstart

Build and install your first Script Mod extension in minutes.

Script Mod API

Register UI surfaces, components, pages, actions, and service calls.

Native Mods

Write Kotlin DEX mods with full Android and Compose access.