What it is
Rusty Requester builds, sends, and inspects HTTP requests. It is a desktop
application written in Rust on the egui immediate-mode toolkit,
so it draws its own interface instead of shipping a browser engine to draw
it. There is no account, no sign-in, and no background sync. Your workspace
is one JSON file on your own disk.
The name is a double meaning. Rust the language, and rust as in older hardware that still does the job: the readme states that developers on older or low-spec machines are who this is built for first.
It is a graphical application, not a command-line tool. The binary accepts
exactly one flag, --version, and everything else happens in the
window. If you were looking for a scriptable HTTP client, curl
is still the right answer, and this app will paste your curl
commands in and hand them back as redacted snippets.
This page covers installation and the reference tables you will want at hand. The task-by-task guide, covering the request builder, environments, auth, the collection runner, imports, exports, backups, and troubleshooting, lives in the full guide.
Install
curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | bash
The installer asks latest.json on this site which
release is current, and falls back to the GitHub Releases API if that file
cannot be reached. Pin a version with VERSION= instead.
What the installer does
- macOS
-
Downloads
RustyRequester-vX.Y.Z-macos-universal.dmg, mounts it, copiesRustyRequester.appinto/Applications(or~/Applicationswhen the system folder is not writable), quits a running instance, removes the Gatekeeper quarantine attribute, re-registers the bundle with Launch Services, and prints the installed binary's SHA-256. - Linux
-
Downloads
RustyRequester-vX.Y.Z-linux-x86_64.tar.gz, extracts it, and runs the bundledinstall-local.sh, which puts the binary in~/.local/binand registers a.desktopentry. Nosudo. If~/.local/binis not on yourPATH, the script says so and prints the line to add.
Installer environment variables
| Variable | Effect |
|---|---|
VERSION | Install a specific release tag instead of the current one. |
UNINSTALL=1 | Remove the installed app. Keeps your data. |
PURGE=1 | With UNINSTALL=1, also delete the data directory. |
SKIP_QUARANTINE_STRIP=1 | macOS only. Leave Gatekeeper's quarantine attribute in place, so you confirm the first launch yourself. |
RUSTY_REPO | Pull release assets from another owner/name repository. |
RUSTY_LATEST_JSON_URL | Point version resolution at a different metadata URL. |
Uninstall
curl -fsSL https://raw.githubusercontent.com/chud-lori/rusty-requester/main/install.sh | UNINSTALL=1 bashAdd PURGE=1 to delete the data directory as well.
Build from source
git clone https://github.com/chud-lori/rusty-requester
cd rusty-requester
make release
make run builds and runs a debug build, make app builds
a macOS bundle, make app-install builds it and copies it to
/Applications, and make help lists every target.
Plain Cargo works too.
First launch on macOS
The app is not notarised by Apple, so a manually installed copy triggers the
"cannot be opened because Apple cannot check it" dialog once. Right-click the
app and choose Open, or approve it under System Settings, Privacy and Security.
The one-line installer removes the quarantine attribute for you, so it does not
hit this at all unless you set SKIP_QUARANTINE_STRIP=1.
Reference
Every row below is read out of the source of v0.28.4. Filter across all six tables at once.
Nothing in the reference matches that.
The filter searches every cell of the six tables below. Try a shorter word, or clear the filter to see all of it. If what you are after is a task rather than a setting, the full guide is organised by task.
Keyboard shortcuts
Cmd on macOS, Ctrl on Linux and Windows. One binding covers both, because egui maps them to the same modifier.
| Keys | Action |
|---|---|
| Cmd Enter | Send the active request. Ignored while a send is already in flight. |
| Cmd N | New draft request. |
| Cmd W | Close the active tab. |
| Cmd D | Duplicate the active tab. |
| Cmd S | Save. A draft opens the save-to-folder dialog, a saved request writes and clears its unsaved marker. |
| Cmd F | Find in the response body. Switches to the Body tab and focuses the search field. |
| Cmd K | Focus the sidebar search field. |
| Cmd P | Request finder. Fuzzy-search requests across every collection. |
| Shift Cmd P | Actions palette. Every command in the table below, by name. |
| F2 | Rename the active request. |
| Up Down | Step through the sidebar request list. Only while no text field has focus and no dialog is open, so typing is never hijacked. |
| Esc | Close the open dialog, palette, or inline search bar. |
| Cmd , | Preferences. macOS only, through the native menu bar. |
| Cmd O | Import a collection file. macOS only, through the native menu bar. |
| Shift Cmd C | Toggle the code snippet panel. macOS only, through the native menu bar. |
The last three are accelerators on the macOS NSMenu bar, which
Linux does not get. On Linux, reach those three through the actions palette.
Actions palette
Open with Shift Cmd P and type. The palette matches on the name and on the extra search words listed here, so you do not have to remember the exact wording.
| Action | Also matches | Keys |
|---|---|---|
| New request | create add tab | Cmd N |
| Duplicate tab | clone copy tab | Cmd D |
| Close tab | close window | Cmd W |
| Toggle pin tab | pin unpin sticky | |
| Save draft to folder | save persist folder collection | Cmd S |
| Copy as cURL | curl command line shell | |
| Toggle code snippet panel | code panel side python javascript fetch httpie | Shift Cmd C |
| Open environments | env variables vars | |
| Open settings | preferences timeout proxy tls | Cmd , |
| Paste cURL command | curl import clipboard | |
| Collection Runner | runner collection run batch data rows csv json report | |
| Workspace Sync | sync git workspace openapi refresh import export | |
| Import collection file | import postman json yaml | |
| Create workspace backup | snapshot restore data safety | |
| Backups | restore snapshot data safety location | |
| Export all as JSON | export backup json | |
| Export all as YAML | export backup yaml | |
| Clear history | delete wipe log | |
| Toggle sidebar History and Collections view | switch toggle sidebar history collections | |
| About Rusty Requester | about version credit help |
Settings
Everything the Settings dialog exposes, with the value you get if you never
open it. Settings are stored per workspace in data.json.
| Setting | Default | Range and meaning |
|---|---|---|
| Request timeout | 60 s |
0 to 3600 seconds. 0 disables the timeout, so a request can hang until you cancel it. |
| Max response body | 50 MB |
0 to 2048 MB. Anything past the cap is discarded and the response shows a truncation banner. 0 removes the cap, and a large enough payload can then exhaust memory. |
| Proxy URL | empty | HTTP, HTTPS, or SOCKS5, for example http://proxy:8080. Empty means connect directly. |
| Verify TLS certificates | on | Turning it off accepts self-signed and expired certificates. Useful against an internal dev API, dangerous on the public internet. |
| Theme | Dark | Dark, Light, or Postman. Method colors and status pills are retuned per theme. The dialog previews the change before you save it. |
| Enable Workspace Sync | off | Opt-in local workflow for Git workspace import and export and OpenAPI refresh. While it is off, the app never reads or writes a Git workspace, and nothing runs in the background. |
| Check for updates on launch | on | One silent GET to the public latest.json per launch. Turn it off for zero outbound traffic at startup. |
Code snippet languages
The snippet panel renders the active request in each of these. Snippets are redacted by default, so obvious secrets are masked while the request shape stays intact. Copying the raw version is a separate, explicit action.
| Language | Form |
|---|---|
| cURL | Shell command |
| Python | The requests library |
| JavaScript | fetch |
| HTTPie | Shell command |
Files on disk
| Platform | Workspace file |
|---|---|
| macOS | ~/Library/Application Support/rusty-requester/data.json |
| Linux | ~/.local/share/rusty-requester/data.json |
| Windows | %LOCALAPPDATA%\rusty-requester\data.json |
One plaintext JSON file holds collections, history, settings, and any token or password you typed into Auth or an environment variable. The app relies on your home directory's permissions to protect it. Do not commit it. A panic log and the update log are written beside it. If the file is ever unreadable at startup, the app sidelines it with a timestamped name rather than overwriting it, and tells you where it went.
Command line
| Flag | Effect |
|---|---|
--version, -V | Print the version and exit without opening the window. Useful for confirming which build is actually on disk when Launch Services has cached an old one. |
That is the whole command-line surface. Every other flag is ignored.
Platforms
Two release artifacts are built, and nothing else is published:
- macOS
- A universal disk image covering Apple Silicon and Intel, built on the GitHub
macos-latestrunner. - Linux
- An
x86_64tarball, built on Ubuntu 22.04 so it links against glibc 2.35. That covers Ubuntu 22.04 and newer, Debian 12, Fedora 36 and newer, and RHEL 9. The build is pinned to 22.04 on purpose, because a binary built on a newer runner needs a newer glibc than many desktops have. - Linux on ARM
- Not built. The installer refuses any Linux architecture other than
x86_64and tells you to build from source. - Windows
- No release is published and the installer refuses to run. The source carries Windows branches and the app reads a Windows workspace path, so a local
cargo buildis the only route today. Whether Windows becomes a supported target is an open question, not a promise.
What the release contains
- One binary. No bundled browser engine, no Node runtime, no separate helper processes. The interface is drawn by
egui. - Built for size. The release profile uses
opt-level = "z", link-time optimisation, a single codegen unit, and strips symbols. Actual artifact sizes are listed on each release, so read them from there rather than from a marketing number here. - 561 package entries in
Cargo.lock. Count it yourself withgrep -c '^\[\[package\]\]' Cargo.lock. That includes the app itself and every platform-specific and build-time dependency, so it is an upper bound on what any one target compiles. - Versioned with semver, pre-1.0.
data.jsonreads forward throughserdedefaults, but a minor release can still change field shapes. The 1.0 line is where the on-disk schema, install paths, and export formats get locked.
Security
An API client sits on a trust boundary. You type a URL and a stranger's server sends bytes back. What the app guarantees about those bytes:
- Response content is never executed. HTML renders as markup through
egui, with no DOM and no JavaScript engine. A<script>tag is displayed as text. - Pasting a cURL command never runs a shell. The flags are parsed as data.
- TLS and HTTP go through
reqwest,hyper, andrustls, in safe Rust, which rules out the buffer-overflow class of bug a C client has to defend against. - Runner reports leave secrets out. Exported reports omit response bodies, headers, cookies, and extracted values, and redact query strings and fragments from URLs.
- Sharing is redacted by default. Code snippets mask obvious secrets, and collection exports can be scanned and redacted locally before anything is written. Copying the raw version is always a separate, deliberate action.
- No telemetry, no analytics, no account. The only outbound traffic is the requests you send, plus one optional update check that reads public release metadata. That check is a single switch in Settings.
What you still own: requests you aim at your own machine or internal network,
files you save and then open in something else, and the fact that
data.json and any exported collection folder are plaintext on your
disk. A private Git repository is access control, not encryption. The full
threat model and how to report a vulnerability are in
SECURITY.md.