A native, offline, lightweight API client built with Rust and egui —
a Postman alternative that doesn't chew through hundreds of MB of RAM just to make HTTP requests.
Why "Rusty"? It's a double pun on Rust (the language) and rust-as-in-old-stuff-that-still-works. Plenty of developers are on older / low-spec machines that can't stomach a 500 MB Electron app with half a gig of idle RAM — so this is built for them first. ~15 MB binary, ~30 MB idle RAM, <100 ms cold start.
Most API clients today are Electron apps — Chromium + Node wrapped
around a form builder. That buys you cross-platform consistency at the
cost of hundreds of MB of RAM and a supply chain with thousands of npm
packages. Rusty Requester is a single ~15 MB native binary: Rust +
egui, no webview, no Node, no account.
| Postman | Insomnia | Bruno | Rusty Requester | |
|---|---|---|---|---|
| Runtime | Electron | Electron | Electron | Rust + egui (native) |
| Download size | ~500 MB | ~200 MB | ~200 MB | ~15 MB |
| Idle RAM | 400–800 MB | 300–500 MB | 200–400 MB | ~30 MB |
| Cold start | 2–5 s | 1–3 s | 1–2 s | <100 ms |
| Account required | yes (for sync) | yes (gated 2023) | no | no |
| Telemetry | yes | yes | off by default | none |
| Storage | cloud-first | cloud or local | git-native files | local app data + optional reviewable .rr files |
| Supply chain | ~1000+ npm deps | ~1000+ npm deps | ~800 npm deps | ~150 Rust crates |
| Response HTML | Chromium webview | Chromium webview | Chromium webview | egui text/markup — no JS engine |
Bruno is the closest match in spirit (offline, file-based, OSS) — it's a good product. The differentiator is runtime: it still ships Chromium.
- Memory safety. A malformed response can't buffer-overflow the parser the way a C client could. Rust's bounds checks and borrow-checker eliminate a whole class of CVE.
- No JS runtime means no JS CVEs. Response HTML renders as markup
in
egui, not in a Chromium webview. A hostile server can't hit you with a V8 exploit because there's no V8. - Smaller attack surface. ~150 Rust crates vs ~1000+ npm packages per Electron competitor. Fewer transitive deps = fewer places for a supply-chain compromise to land.
- Well-audited networking.
reqwest+rustls(ornative-tls) handle TLS and redirects — both heavily used across the Rust ecosystem. - Honest caveat. Rust isn't magically safe from supply-chain
attacks. We mitigate with
Cargo.lockpinning, sticking to widely-used crates (reqwest,tokio,serde,egui), and runningcargo auditbefore every release — but a compromised upstream would still bite us.
Tabbed request editor, per-environment variables + cookie jar,
Postman Collection v2.1 import, syntax-highlighted JSON (with
Postman-style fold chevrons on every { / [) / Tree / HTML / SSE
views, Server-Sent Events streaming for LLM APIs, Cancel
mid-flight, Response diff across sends, Collection Runner with
CSV/JSON data rows, presets, detail drilldowns, scoped runs, safe
CSV/HTML reports, redacted code snippets, Git-friendly workspace
exports, file-backed collection folders with readable .rr request files,
status/diff review, pull/commit/push through your local Git credentials,
OpenAPI refresh, request finder + actions palette (Cmd on macOS,
Ctrl on Linux/Windows), and platform menus. Full catalog in
docs/FEATURES.md and the usage guide in
docs/usage.html.
An API client lives on a trust boundary — you type a URL, a stranger's server sends bytes back. The headline guarantees:
- No auto-download / no code execution on response content — save
goes through the OS dialog, HTML renders as markup (no DOM, no JS
engine),
<script>tags display as text. - No memory-corruption path — TLS + HTTP via
reqwest/hyper/rustls, all safe Rust. No C-client buffer-overflow class of CVE. - No shell execution on
curlpaste — flags are parsed as data, neverexec'd. - Secret-aware sharing — code snippets are redacted by default, and collection exports can be scanned locally before writing files.
You still own: SSRF from your own machine (localhost, internal IPs),
files you explicitly save and then open in a vulnerable downstream app,
and plaintext local data under your home directory or collection Git folders.
App data is kept local with restrictive file permissions where supported;
collection exports mask secrets by default, but private repos are still access
control, not encryption. Full threat model + vulnerability reporting in
SECURITY.md.
curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | bashThe installer auto-detects your platform and pulls the matching release asset:
- macOS (universal, Apple Silicon + Intel) —
RustyRequester-vX.Y.Z-macos-universal.dmg. CopiesRustyRequester.appinto/Applications(falls back to~/Applicationsif the system folder isn't writable), quits any running instance, strips the Gatekeeper quarantine attribute, and re-registers with Launch Services so Dock / Spotlight pick up the new bundle. - Linux (x86_64 glibc 2.35+, so Ubuntu 22.04 / Debian 12 /
Fedora 36+ / RHEL 9 and newer) —
RustyRequester-vX.Y.Z-linux-x86_64.tar.gz. Installs the binary directly at~/.local/bin/rusty-requester, drops a.desktopentry into~/.local/share/applications, and puts icons in bothhicolor/512x512/apps/andpixmaps/. User data lives separately at~/.local/share/rusty-requester/data.jsonso the two never get tangled. Nosudo. If~/.local/binisn't on yourPATH, the script tells you how to add it.
Install a specific version:
curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | VERSION=v0.3.0 bashmacOS: keep the Gatekeeper quarantine attribute (you'll do the "right-click → Open" dance yourself on first launch):
curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | SKIP_QUARANTINE_STRIP=1 bashAfter it finishes, launch:
open /Applications/RustyRequester.app # macOS
rusty-requester # Linux (if ~/.local/bin on PATH)macOS — grab RustyRequester-vX.Y.Z-macos-universal.dmg from the
Releases page,
open the .dmg, drag RustyRequester.app onto the Applications
shortcut, eject the disk image.
Linux (x86_64 glibc) — grab RustyRequester-vX.Y.Z-linux-x86_64.tar.gz,
extract it, run ./install-local.sh inside, then rusty-requester
(ensure ~/.local/bin is on your PATH).
The app isn't notarised by Apple (no paid developer account), so macOS will refuse to open it on the first launch with "can't be opened because Apple cannot check it for malicious software" — unless you installed with the one-liner above, which auto-strips the quarantine flag.
If you used the manual install, work around it once:
- Right-click the app → Open → confirm in the dialog, OR
- System Settings → Privacy & Security, scroll down, and click "Open Anyway" next to the Rusty Requester entry
You only need to do this once.
The same one-liner in UNINSTALL=1 mode removes the app and
preserves your data.json (collections, history, OAuth tokens):
curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | UNINSTALL=1 bashAdd PURGE=1 to wipe user data too:
curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | UNINSTALL=1 PURGE=1 bashOr, if you still have the extracted Linux tarball around, run
./uninstall-local.sh (pass --purge to also delete data). macOS:
the one-liner removes RustyRequester.app from /Applications
(or ~/Applications), quits any running instance, and
— with PURGE=1 — clears
~/Library/Application Support/rusty-requester.
git clone https://github.com/chud-lori/rusty-requester
cd rusty-requester
make run # debug build + run
make release # optimized binary at target/release/rusty-requester
make app # build a macOS .app bundle (in target/bundle/)
make app-install # build the bundle and copy it to /Applications
make help # list all targetsOr use Cargo directly: cargo run, cargo build --release, cargo test.
Requires Rust 1.73+ — install via rustup.rs.
- Click ➕ New Collection in the sidebar.
- Inside the collection, click ➕ Request.
- Pick a method, enter a URL (paste a
curlcommand instead — it'll auto-fill method, headers, body, auth, etc.). - Click Send (or press ⌘/Ctrl + Enter).
All edits auto-save to a single local JSON file — nothing leaves your machine:
- macOS:
~/Library/Application Support/rusty-requester/data.json - Linux:
~/.local/share/rusty-requester/data.json - Windows:
%LOCALAPPDATA%\rusty-requester\data.json
Security note:
data.jsonis a plaintext file holding your requests and any tokens / passwords you put into Auth or Environment variables. Rusty Requester trusts local disk permissions to protect it —0600on Unix by default because it lives under your home directory. Don't commitdata.jsonto a repo, don't share it with anyone you wouldn't share your tokens with, and consider symlinking it onto an encrypted volume if your setup warrants it. Native-keychain integration is on the post-1.0 roadmap.
⌘⏎ Send · ⌘N New request · ⌘W Close tab · ⌘D Duplicate tab · ⌘F Find in response · ⌘K Focus search · ⌘P Command palette · ⇧⌘P Actions palette · F2 Rename · Esc Dismiss modals
(Use Ctrl instead of ⌘ on Linux / Windows — the app binds both.)
The ⇧⌘P actions palette is self-discoverable — open it and start typing to see every available action.
Open Collection Runner… from the Actions Palette or the native Request menu to run saved requests as a batch. Pick all collections or a specific folder scope, paste optional CSV/JSON data rows, then watch live per-request progress. Reports export to CSV or HTML without response bodies, headers, cookies, extracted values, or full query strings.
Full usage guide, body modes, environment-variable examples, import /
export, and UI conventions in docs/FEATURES.md.
Rusty Requester follows Semantic Versioning.
Pre-1.0 (current): data.json reads forward cleanly via
#[serde(default)] guards, but minor releases may still break
field-level shapes. The 1.0 line locks down the on-disk schema, install
paths, CLI flags, import / export formats, and public macOS shortcuts —
full policy in
docs/ARCHITECTURE.md#compatibility--stability.
See CHANGELOG.md for what's shipped.
docs/FEATURES.md— full feature list, usage walkthroughs, UI conventions, roadmapdocs/ARCHITECTURE.md— dependencies, source layout, design notes, release flow, semver policySECURITY.md— threat model + vulnerability reportingCHANGELOG.md— version history
- Fork the repo
git checkout -b feature/my-thingcargo test && cargo clippy --all-targets -- -D warnings && cargo fmt --all -- --check- Commit, push, open a PR
MIT — see LICENSE.
Created by @chud-lori.