Skip to content

Repository files navigation

Rusty Requester
Rusty Requester

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.

Rust macOS Linux


🎯 Why Rusty Requester?

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.

vs Postman / Insomnia / Bruno

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.

Why Rust for an API client?

  • 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 (or native-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.lock pinning, sticking to widely-used crates (reqwest, tokio, serde, egui), and running cargo audit before every release — but a compromised upstream would still bite us.

Highlights

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.


🔐 Security

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 curl paste — flags are parsed as data, never exec'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.


📥 Install

One-line install (macOS + Linux)

curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | bash

The installer auto-detects your platform and pulls the matching release asset:

  • macOS (universal, Apple Silicon + Intel) — RustyRequester-vX.Y.Z-macos-universal.dmg. Copies RustyRequester.app into /Applications (falls back to ~/Applications if 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 .desktop entry into ~/.local/share/applications, and puts icons in both hicolor/512x512/apps/ and pixmaps/. User data lives separately at ~/.local/share/rusty-requester/data.json so the two never get tangled. No sudo. If ~/.local/bin isn't on your PATH, 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 bash

macOS: 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 bash

After it finishes, launch:

open /Applications/RustyRequester.app     # macOS
rusty-requester                           # Linux (if ~/.local/bin on PATH)

Manual install

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).

First launch — Gatekeeper (macOS)

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.

Uninstall

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 bash

Add PURGE=1 to wipe user data too:

curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | UNINSTALL=1 PURGE=1 bash

Or, 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.

Build from source

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 targets

Or use Cargo directly: cargo run, cargo build --release, cargo test. Requires Rust 1.73+ — install via rustup.rs.


🚀 Quickstart

  1. Click ➕ New Collection in the sidebar.
  2. Inside the collection, click ➕ Request.
  3. Pick a method, enter a URL (paste a curl command instead — it'll auto-fill method, headers, body, auth, etc.).
  4. 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.json is 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 — 0600 on Unix by default because it lives under your home directory. Don't commit data.json to 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.

Useful shortcuts

⌘⏎ 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.

Collection Runner

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.


🛡 Compatibility & stability

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


🤝 Contributing

  1. Fork the repo
  2. git checkout -b feature/my-thing
  3. cargo test && cargo clippy --all-targets -- -D warnings && cargo fmt --all -- --check
  4. Commit, push, open a PR

📝 License

MIT — see LICENSE.

📬 Contact

Created by @chud-lori.

About

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

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages