Aether is designed as a "Write Once, Deploy Anywhere" framework, leveraging Kotlin Multiplatform (KMP) to abstract platform-specific details while providing high-performance implementations for each target.
aether-core: The brain. Contains the Exchange, Pipeline, UserContext, and platform-agnostic Dispatcher.aether-web: The router. Implements a Radix Tree for O(k) route matching.aether-db: The data layer. A Django-style ORM that builds a Query AST.aether-grpc: The RPC layer. Code-first gRPC with gRPC-Web, Connect protocol, and native HTTP/2 support.aether-ui: The view layer. A Composable DSL for Server-Side Rendering (SSR).aether-forms: The validation layer. Handles HTML form generation and data cleaning.aether-admin: The administration layer. Provides an auto-generated CRUD interface for models.aether-net: The transport layer. Abstracts TCP/UDP/WebSocket connections.aether-ksp: The code generation layer. KSP processors for tasks, migrations, and proto generation.TcpTransport (JVM/Vert.x) or a Wasm fetch event.Router middleware matches the path and extracts parameters.On the JVM, Aether uses Executors.newVirtualThreadPerTaskExecutor(). This means you can write blocking code (like JDBC calls) without blocking an OS thread. The runtime automatically suspends the virtual thread, allowing massive concurrency (millions of threads).
On Wasm (JS/WASI), Aether uses standard Kotlin Coroutines. I/O operations are non-blocking and suspend execution, returning control to the single-threaded event loop.
Aether DB does not simply concatenate SQL strings.
Users.filter(...)).DatabaseDriver translates the AST into the specific SQL dialect (PostgreSQL, SQLite, etc.) or even an HTTP request (for Wasm clients talking to a data API).Aether supports multi-protocol RPC with a code-first approach:
| Protocol | Transport | Platforms |
|---|---|---|
| gRPC-Web | HTTP/1.1 or HTTP/2 | All (JVM, Wasm) |
| Connect | HTTP/1.1 or HTTP/2 | All (JVM, Wasm) |
| Native gRPC | HTTP/2 | JVM only |
The GrpcMode.BEST_AVAILABLE setting automatically selects native mode on JVM and adapter mode elsewhere.
Instead of writing .proto files manually, you define services in Kotlin:
@AetherMessage
data class User(@ProtoField(1) val id: String, @ProtoField(2) val name: String)
@AetherService
interface UserService {
@AetherRpc
suspend fun getUser(request: GetUserRequest): User
}
The KSP processor generates equivalent .proto files for interoperability with other languages.
Authentication works identically for REST and gRPC through UserContext:
// Works in both REST handlers and gRPC methods
val user = currentUser() // Returns Principal from coroutine context
The AuthMiddleware (REST) and gRPC interceptors both propagate the authenticated principal via Kotlin's CoroutineContext, enabling seamless auth across protocols.
