Close to your data.
Entirely in Rust.

A local-first web framework. Render on the server. Query in the browser. Write your app in one language.

Rust in. A living interface out.

Real queries. Real writes. No app JavaScript.

Rust
// Query excerpt. Server and browser.
let issues = live_query! {
    DemoItem from i in IssueRow
    where if $(!search.get().is_empty()) {
        i.title contains $(search.get())
    }
    order by i.position
    select {
        id: i.id,
        title: i.title,
        open: i.open
    }
};
Simplified source excerpts. Full demo: site/src/pages.rs.
A little issue trackerLocal query
  • Make the first render count
  • Keep filters close to the data
  • Let the server check the writes
  • Ship something worth opening

No matches. Try a different filter.

Try a filter. Tick a row.Built with hearth

Illustrative data, isolated to this browser. Filter locally; toggle a row to make an optimistic write, validated by the Rust server.

The first view comes from the server.
The next move is yours.

One source of truth.

Declare a table, authorize its rows, and write a query. Hearth uses that query for the initial render and the browser's live results.

#[derive(Table)]
live_query! { ... }

HTML, already useful.

The server sends rendered content. Client expressions compile to small JavaScript modules. No client-side Rust or WebAssembly download.

Rust → HTML + JavaScript

Keep the data close.

Indexed queries run against local tables. Writes update the interface immediately, then the server validates them. Rejected writes roll back.

local query → update → sync

Less between
you and the app.

Not another data layer to wire into your stack. A framework for the page, the data, and the space between.

Rust all the way down
Views, handlers, read scopes and write validation live together. The framework generates the browser code.
Local queries, live results
Filter, join and sort without a request for every interaction. Keyed lists update when their data changes.
The server stays in charge
Read scopes are mandatory. Writes are explicitly allowed and checked on the server. Browser state is never authorization.
A small, familiar stack
Toasty models. SQLite for development. Tailwind when you want it. Same-origin script modules that work under a strict CSP.

Make yourself
at home.

Hearth is early, opinionated, and ready to be explored. Start with a small app. Tell us where it gets in your way.

Build your first page

Start 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 --locked

Hearth 0.1.0 is published. Use Rust 1.99.1, then follow the guide for a complete first page. No Node.js or pnpm required for your app.

See setup and running instructions →

An honest starting point.

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 →