Skip to main content
Each extension gets a private persistent key-value store. Data survives hot-reloads and app restarts because Aether backs the store by ~/.aether/app-extension-state.json inside the Alpine filesystem. No other extension can read or write your extension’s storage.

API reference

All storage methods are synchronous.

Reading a value

Pass an optional fallback as the second argument to get(). The fallback is returned when the key does not exist:

Writing a value

Deleting a value

Clearing all extension storage

Getting a full snapshot

snapshot() returns a plain object containing all key-value pairs currently stored by your extension:

Using storage in a surface render

The following example wires a persistent counter to a surface rendered above the chat composer:
The storage object passed to your surface’s render function is a snapshot taken at render time. Every storage.set(), storage.delete(), and storage.clear() call automatically triggers a re-render — you do not need to call aether.invalidate() after a storage write.
Store only JSON-serializable values — strings, numbers, booleans, plain objects, and arrays. Functions and class instances will not be persisted correctly.