Three extension tiers
Each tier targets a different layer of the Aether stack with a different language, loading model, and access surface.| Tier | Language | Loading | Access Level |
|---|---|---|---|
pi.extensions | TypeScript/JS | Hot-reload | Pi agent tools, commands, hooks |
aether.extensions | TypeScript/JS | Hot-reload | Aether Script Mod API v2 (UI, state, services) |
aether.native | Kotlin/DEX | On process start (requires restart) | Full Android, Compose, and reflection |
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 singlepackage.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
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 → Import and select the zip file. Aether extracts the package into
~/.aether/extensionsand loads it immediately. - npm packages: add the package through Aether’s package management interface and declare
aether.extensionsentries in itspackage.json. Aether discovers and loads it alongside locally installed extensions.
Hot reload
Script Mod changes — any modification to api.extensions or aether.extensions entry file — reload automatically without restarting Aether. The extension runtime re-imports the updated file, calls your factory function again, and triggers a UI refresh. 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.