Build local-first desktop workflow tools with plain frontend files.
Native window. Embedded SQLite. Scoped machine access. No full desktop project on day one.
Get Started · Fit Guide · Architecture · Runtime · Example Apps · All Docs
RustFrame is not trying to be the next everything-framework for desktop apps.
It is a narrower bet:
workflow tools that are too native for a browser tab, but too small to deserve a full desktop framework project from day one
That means apps that are mostly frontend code, but still need:
- a real desktop window
- local SQLite
- scoped filesystem access
- one or two allowlisted automations
- packaging into a real installable desktop app
If that is not your shape, RustFrame is probably the wrong tool. That honesty is part of the pitch.
- If a browser tab is enough, use a browser tab.
- If you already know you need deep native APIs, broad plugins, or a mature ecosystem, use Tauri, Electron, or a native stack.
- If your app is mostly HTML, CSS, and JavaScript but still needs a desktop shell, local data, and a tight native surface, RustFrame is where it starts to make sense.
The painful part of many small desktop tools is not the UI.
It is all the scaffolding around the UI:
- the native project
- the bridge layer
- the SQLite glue
- the packaging story
- the capability boundaries
- the awkward jump from "simple tool" to "needs a bit more native control"
RustFrame tries to make that path smaller without pretending the desktop disappears.
The flagship app is apps/research-desk.
If you want to decide whether RustFrame is useful, do not start with the template. Start here:
cargo run -p rustframe-cli -- dev research-deskresearch-desk is the clearest proof of the wedge today. It:
- indexes a bundled local archive into SQLite
- reads real files through scoped filesystem roots
- runs an allowlisted Python indexer from the UI
- opens reader windows for focused review
- exports the visible review queue
That is the current answer to "why not just a browser tab?"
RustFrame changes the default authoring model.
Your app starts as a plain folder:
apps/<name>/
├── index.html
├── styles.css
├── app.js
├── rustframe.json
├── assets/
└── data/
├── schema.json
├── seeds/
└── migrations/
The runtime owns the rest:
- the native window
- the injected
window.RustFramebridge - embedded assets
- SQLite provisioning and migrations
- scoped filesystem access
- allowlisted shell execution
- packaging and host validation
- the eject path when the app outgrows the hidden runner
That keeps the early path small while still leaving a way out later.
Use RustFrame when:
- your app should stay mostly frontend code
- you want local SQLite without building the full desktop stack yourself
- you need a native window, local files, and a few explicit machine capabilities
- you want packaging, export, and capability boundaries to be runtime-owned
- you want to eject only after the product earns that complexity
Do not use RustFrame when:
- the product works fine as a normal web app or PWA
- you need deep platform integrations immediately
- you want a large desktop ecosystem from day one
- you need Chromium-level rendering consistency everywhere
- you are already productive in Tauri, Electron, or native and not feeling friction
| Question | Browser tab | RustFrame | Tauri / Electron |
|---|---|---|---|
| Native desktop window | No | Yes | Yes |
| Embedded local SQLite by default | No | Yes | Possible |
| Scoped filesystem and allowlisted commands | Limited | Yes | Yes |
| Plain frontend folder as the default app shape | Yes | Yes | Not usually |
| Mature plugin ecosystem | N/A | No | Yes |
| Best for narrow local-first workflow tools | Sometimes | Yes | Sometimes |
| Best for broad desktop app ambitions | No | No | Yes |
The point is not "RustFrame beats Tauri." The point is that there is a smaller product slice where RustFrame can be the cleaner starting shape.
RustFrame already includes:
- a runtime crate built on
taoandwry - a CLI that can
new,doctor,dev,inspect,reset-data,export,platform-check,package --verify, andeject - runtime-owned
window.RustFrameinjection instead of per-app bridge duplication - embedded SQLite with schema files, immutable seeds, versioned SQL migrations, and runtime full-text search
- scoped filesystem helpers for reads, writes, dialogs, open, and reveal
- hardened shell capabilities with explicit timeout and output limits
local-firstandnetworkedtrust models- clipboard writes and multi-window state persistence
- host-native packaging flows for Linux, Windows, and macOS
- workflow-first starters plus Vite, React Vite, Vue Vite, and Svelte Vite starters
- a community template catalog and ecosystem docs for sync and capability extension patterns
- automated tests and workflow smoke coverage
Prerequisites:
- Rust and Cargo
- a native host toolchain for the platform you are targeting
- Linux uses the GTK and WebKitGTK stack required by
wry - Windows uses the MSVC Rust toolchain
- macOS uses Xcode command line tools
Check the host first:
cargo run -p rustframe-cli -- doctorRun the flagship workflow:
cargo run -p rustframe-cli -- dev research-deskGenerate a new app:
cargo run -p rustframe-cli -- new hello-rustframeRun it:
cargo run -p rustframe-cli -- dev hello-rustframeInspect the resolved contract:
cargo run -p rustframe-cli -- inspect hello-rustframeExport the raw binary:
cargo run -p rustframe-cli -- export hello-rustframePackage and verify a host-native bundle:
cargo run -p rustframe-cli -- package hello-rustframe --verifyIf you want to develop with a frontend dev server:
cargo run -p rustframe-cli -- dev hello-rustframe http://127.0.0.1:5173Starter source for Vite, React Vite, Vue Vite, and Svelte Vite lives under examples/frontend-starters/.
Phase 5 added a small ecosystem surface, but it stays tied to the wedge:
The machine-readable template catalog lives here:
examples/community-templates/catalog.json
The rule is simple: ecosystem only after fit. One credible flagship workflow matters more than a hundred random demos.
RustFrame is promising, but still early:
- the ecosystem is small
- deep native integration is not the default path
- signing and updates are documented, but still handled at the release-pipeline layer
- Linux still carries heavier GTK, WebKitGTK, and display-stack constraints
- cross-host validation still depends on the matching native host toolchain
Those are not footnotes. They define the real shape of the project today.
RustFrame now has a clearer shipping contract for small production tools:
Repo CI also verifies packaged bundles on supported hosts.
crates/rustframeReusable runtime crate.crates/rustframe-cliScaffolding, validation, export, packaging, and ejection tooling.apps/research-deskFlagship local archive review workflow.apps/hello-rustframeDefault workflow-first starter app.examples/frontend-starters/Optional frontend-stack starters.examples/capability-demoSample app proving the bridge, filesystem scope, and shell model.docs/Product and implementation docs.site/Portable static site derived from the repo.
- Getting Started
- Choosing RustFrame
- Architecture Overview
- Runtime And Capabilities
- Frontend App Rules
- Example Apps
The shortest useful next step is still:
cargo run -p rustframe-cli -- dev research-desk