A Rust + Svelte 5 framework for hyper-responsive desktop apps. Laravel's ergonomics — container, providers, middleware, a typed bridge — but compiled, binary, and without runtime overhead.
The CLI is Ratatosk (rata): the squirrel that runs messages up and down
Yggdrasil, between the Rust root and the Svelte crown.
📚 Documentation: elyracode.com/framework (source in
docs/). This page is just a landing page.
- Binary IPC — MessagePack over an
elyra://localhostcustom protocol; no JSON in the hot path. (wire format) #[command] async fndispatched through a middleware pipeline, with a container and providers.EventBus+channel()— Rust→frontend push, batched per flush over a long-poll; the UI thread never blocks. (events)- Typed bridge —
rata codegenturns specta types into TS + a typedapi.*facade. (codegen) - Windows, tray, updater — multi-window, system tray, and an ed25519-verified updater.
- Built-in UI components — a themed About dialog, auto-update toast, and dialogs / toasts / ⌘K palette / context menu.
- Desktop APIs — native dialogs, shell-open, clipboard, notifications, the files the user chose (a dialog's or a drop's, granted so a command can't be handed any other path), window control + file drop, global shortcuts, app menu, a settings store, autostart, and sidecar processes.
- Data — one
Databaseover SQLite/MySQL/Postgres,rata migrate, and#[derive(Model)]Active Record with a query builder and relations. - Live queries —
#[command(live)]: the frontend subscribes, Elyra records what the command read and re-runs it when a write changes it, and every window watching gets the new result — no polling, no reload after save. - Resources —
rata make:resource Customer --generate …writes the vertical slice: a searchable, paged list, a validated form and a detail view in Svelte, the ability-gated commands behind them, tests, and the model, migration and seeder. - A Laravel backend — the desktop half of a Laravel app:
Sanctum sign-in with the token in the keychain, the API's
422s in your forms, its broadcasting into the open windows, working offline, with writes that wait in an outbox and are sent once, its notifications in the OS, counted on the app's icon, and files: uploads streamed from disk, downloads streamed to it, with progress, and queued offline, and what each user may do, from Laravel's permissions (backendfeature). - Every app an MCP server — AI agents call the commands you grant as typed tools, inside the open app or headless, with confirmation in the client.
- Agents that know the framework —
rata ai:installgives coding agents the framework's guidelines and skills, andrata mcp devanswers with the app's commands, models, schema, log and the guides — Laravel Boost for the Rust side, with a Composer package for the Laravel half. - AI SDK — a Laravel-inspired
elyra::ai: agents, tools, structured output, images, and embeddings over Anthropic + OpenAI (aifeature). - Shared facades —
Cache,Storage, andQueuewith the same surface as the Askr/Laravel side, over local backends — one ecosystem, two worlds. - Hardened IPC — a per-run token, origin-scoped CORS, a capability model with deny-by-default sidecar spawn, a default CSP, and bounded request bodies.
- Laravel ergonomics —
Log,Config,Secrets,TestApp, a schema builder + seeders, and Eloquent-style pagination / aggregates / joins / soft deletes / transactions.
elyra-framework/
├── framework/ # elyra — App, Container/Ctx, Command, events, shell (tao+wry)
├── macros/ # elyra-macros — #[command] and #[derive(Model)]
├── database/ # elyra-db — Database, migrations, models (GUI-free)
├── ratatosk/ # ratatosk — the `rata` CLI
├── runtime/ # @elyra/runtime — invoke(), channel(), generated api.*
└── example/ # elyra-example — the demo app / DX benchmark
rata new myapp # scaffold (see docs/getting-started.md)
cd myapp
(cd app && npm install && npm run build)
rata codegen # generate typed bindings
cargo run # launchOr run the bundled demo from this repo — no npm needed (serves a built-in fallback page):
cargo run -p elyra-exampleuse elyra::{command, commands, App, Ctx};
#[command]
async fn greet(_ctx: Ctx, name: String) -> String {
format!("Hello, {name}!")
}
fn main() -> elyra::Result<()> {
App::new()
.commands(commands![greet])
.assets(elyra::asset_resolver::<Assets>())
.run()
}import { api } from "./bindings"; // generated by `rata codegen`
const greeting = await api.greet("World"); // (name: string) => Promise<string>| Feature | Enables |
|---|---|
database |
Database, #[derive(Model)], migrations, App::database |
ai |
elyra::ai — agents, tools, structured output, images, embeddings |
tray |
App::tray, the system tray |
updater |
the updater module (ed25519) |
system |
native dialogs, shell-open, clipboard, notifications, paths |
shortcuts |
OS-level global keyboard shortcuts |
secrets |
Secrets — tokens in the OS keychain |
http |
Http — an HTTP client, Laravel's facade |
backend |
Backend, Auth — a Laravel API, Sanctum sign-in (enables http, secrets) |
elyra = { version = "0.19.0", features = ["database", "tray", "updater", "system", "shortcuts", "secrets"] }v0.19.0 — the current Claude API: the AI SDK speaks
Anthropic's API version 2026-10-21, with structured outputs instead of a
forced tool call, paused turns resumed, refusals as Error::Refused, and
Claude Sonnet 5.5 as the default model. In 0.18: Laravel's abilities on
the desktop: what the signed-in user may do comes from Laravel (spatie's permissions or the Gate, through
Route::elyraAbilities()); a command they may not run is refused before any
request, offline too; the list is kept current when roles change on the
web; and $can(..) and the generated screens hide what they can't do. See
the guide. In 0.17: files between
the desktop and Laravel, uploads and downloads streamed, only files the
user chose, queued offline, with progress (files).
In 0.16: coding agents know the
framework, rata ai:install, rata mcp dev and elyracode/elyra-backend
(coding agents). In 0.15: Laravel's
notifications on the desktop, in the OS or as a toast, the unread count on
the app's icon, read and marked everywhere, and rata make:notifications
(the guide). In 0.14: working
offline, with reads from the last copy and writes that wait in an outbox
and are sent once. In 0.13: broadcasting, so a
change made on the web shows in the open windows, over the Pusher protocol
(Askr's --pusher, Reverb or Pusher).
In 0.12: a Laravel backend, the desktop half of an app whose web half is
Laravel. The app signs in with a Sanctum token kept in the OS keychain, calls
the same API as the web, shows Laravel's 422s in its forms, and
rata make:resource --backend generates the screens over the API. In 0.11:
MCP resource templates. In 0.10.x: hardening, and rata migrate for Rust
migrations. Building on v0.10.0, the AI agents release.
Every Elyra app can be an
MCP server: grant the abilities an agent may use, and the
commands behind them become tools for Claude, Cursor or VS Code, typed from
the same specta types as the frontend's bindings and run through the same
middleware and validation. myapp --mcp works inside the open app, so the
windows update as the agent works, or runs headless when it's closed. The
calls you name (a delete, say) wait for the user to confirm in the client, live
commands are resources an agent can watch, and every call is logged,
dispatched as an event and shown in the app. rata mcp install prints the
client config.
In 0.9: live queries. A #[command(live)] is a command
the frontend subscribes to: Elyra re-runs it when a write changes a table it
read, and pushes the new result to every window watching. rata make:resource
generates live lists and detail views.
In 0.8.0: rata make:resource Customer --generate … — the
vertical slice for a table, from the model and migration to a searchable list,
a validated form and a detail view — on a
hash router and a registry that keeps
main.rs to a one-time edit; translated validation messages and
typed $t.
In 0.7.0: named middleware, a scheduler that runs at clock times and survives sleep, validation of nested input, arrays and the database, and one set of translation files for Rust and Svelte.
Earlier, in 0.6.0: belongs_to_many, casts, scopes and factories; trait-object
and lazy container bindings; domain events with a typed path to the frontend;
durable queues; and test fakes with App::swap.
The rest of the IPC surface was already gated: a random per-run
token, CORS only for the dev origin, a
capability model where destructive routes are opt-in, a
default CSP, deny-by-default sidecar spawn, a policy for shell.open, and
bounded + depth-checked request bodies. The event bus fans out per window
(multi-window apps no longer lose events), a panicking command answers with an
error instead of hanging the caller, and the settings store writes atomically.
The Laravel-shaped gaps are filled: Log,
Config, Secrets over the OS
keychain, TestApp, a schema builder with
Rust migrations + seeders, and Eloquent-style pagination / aggregates / joins /
soft deletes / transactions. Plus queue retries + a failed-job list, typed event
channels in codegen, asset ETag/Range caching, a
cross-platform app menu, and .deb / portable bundling.
Earlier releases brought the core (commands, events, DB/models, codegen, About +
auto-update), native system integration (dialogs, shell-open, clipboard,
notifications, paths), UI components (dialogs, toasts, ⌘K command palette,
context menu), window control + file drop + state persistence, global
shortcuts, a native app menu, a settings store, autostart,
sidecar processes, single-instance + deep-linking, a Laravel-inspired
AI SDK (agents, tools, sub-agents, structured output, streaming,
provider tools, images, audio, embeddings, RAG, plus retries / failover /
caching), and the shared Cache / Storage /
Queue facades over the backend-agnostic
substrate-core contract. See the
changelog and the roadmap.
Every milestone is compiled, clippy-clean and tested — 750 Rust tests and 111 TypeScript tests, with the IPC surface covered end to end and CI running across macOS, Linux and Windows. GUI/OS integrations are launch-smoked, with visual / side-effecting steps called out as unverified.
Full documentation lives at elyracode.com/framework. Start with getting started and the architecture overview, then dive into any topic from the documentation index.
Licensed under the MIT License.
See CONTRIBUTING.md and the Code of Conduct to get involved.