One source of truth.
Declare a table, authorize its rows, and write a query in Rust. Hearth uses that query for the initial render and the browser's live results.
#[derive(Table)]
live_query! { ... }A local-first web framework. Render on the server. Query in the browser. Write your app in one language.
A live Hearth app. Filter the issues, then tick one: the list updates right away and the server checks the write. Sample data that only you see. Open in a new tab ↗
Declare a table, authorize its rows, and write a query in Rust. Hearth uses that query for the initial render and the browser's live results.
#[derive(Table)]
live_query! { ... }The server sends rendered content. Client expressions compile to small JavaScript modules. No client-side Rust or WebAssembly download.
Rust → HTML + JavaScriptIndexed queries run against local tables. Writes update the interface immediately, then the server validates them. Rejected writes roll back.
local query → update → syncNot another data layer to wire into your stack. A framework for the page, the data, and the space between.
Hearth is early and opinionated. Start with a small app, read the source, and tell us where it gets in your way.
Build your first pageStart with crates.io
rustup toolchain install 1.99.1
cargo new my-hearth-app
cd my-hearth-app
rustup override set 1.99.1
cargo add hearth@=0.1.0
cargo add tokio --features rt-multi-thread,macros
cargo install hearth-cli --version 0.1.0 --lockedTested with Rust 1.99.1. Your app does not need Node.js or pnpm.
Setup and running instructions →Hearth is experimental. APIs will change. Browser persistence caches server rows; it is not a durable offline write queue. The current sync path scans scoped tables, so test it with your own data and permissions.
Read the current boundaries →