A terminal client for REST, GraphQL, gRPC, WebSocket, and SSE.
Resterm is a keyboard-driven API client that lives in your terminal and keeps everything local. It stores requests as plain files, supports SSH tunnels, Kubernetes port-forwarding, and OAuth 2.0, and gives you a fast feedback loop with history, diffs, tracing, and profiling.
Quick links: Screenshots, Installation, Quick Start, Features and Documentation.
- Requests live in plain
.http/.restfiles. - Conditional logic -
@when,@skip-if,@if/@elif/@else,@switch/@case, and@for-each. - Multi-step workflows with
@workflow/@step. - Captures, variables, and assertions (
@capture,@var,@assert). - RestermScript - a small, safe expression language purpose.
- OAuth 2.0 (client credentials, password, auth code + PKCE), SSH tunnels, and Kubernetes port-forwards are built in - no extra tools.
- Timeline tracing, profiling, and compare runs across environments.
- Streaming transcripts and an interactive console for WebSocket and SSE sessions.
- No cloud sync, no accounts, no telemetry. Everything stays local.
- There is no AI integration and there will never be.
See the UI in action
Workflows
Trace and Timeline
Profiler
RestermScript
OAuth browser demo (old UI design)
-
Install Resterm using the command that matches your OS.
# Linux/macOS (Homebrew) brew install resterm # Linux (install script) curl -fsSL https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.sh | bash
# Windows (PowerShell) iwr -useb https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.ps1 | iex
-
Bootstrap a tiny workspace.
mkdir my-api && cd my-api resterm init
-
Run it and send your first request.
resterm
Press
Ctrl+Enterin the editor to send the highlighted request.
If you do not want files yet, just run resterm, type a URL in the editor, and press Ctrl+Enter.
If you already have a curl command, paste it into the editor and press Ctrl+Enter to import it.
These are the files you will see most often in a Resterm workspace.
.http/.restfiles store your requests, metadata, and named steps.resterm.env.jsonholds environment variables and secrets for one or more environments.resterm.env.example.jsonis a safe template you can commit and share..rtsfiles contain RestermScript helpers for reuse and small bits of logic.RESTERM.mdis optional project notes created byresterm init.
Protocols and transports cover the following.
HTTP,GraphQL,gRPC,WebSocket, andSSEare supported out of the box.SSH tunnelsinclude host key verification, keep-alives, retries, and persistent sessions.Kubernetes port-forwardstarget pods, services, deployments, and statefulsets with named port resolution, pod readiness checks, retries, and persistent sessions.
Workspace and files focus on the following.
.http/.restfiles are discovered automatically and the request list stays in sync as you edit.- The request editor includes inline syntax highlighting, search, and contextual metadata hints.
- Environment files are treated as first-class input.
resterm initadds resterm.env.json to .gitignore but any custom env files passed via the CLI are not ignored automatically.
Automation and reuse include the following.
- Variables, captures, constants, and multi-step workflows.
- RestermScript (RTS) and optional JavaScript hooks handle request-time logic.
- Curl commands and OpenAPI specs can be imported directly into request collections.
Debugging and inspection provide the following.
Pretty/raw/header/diff/historyviews are available with split panes.- Streaming transcripts are recorded and an interactive console is available for WebSocket and SSE.
- Timeline tracing and profiling help find slow or flaky endpoints.
Security and auth cover the following.
- OAuth 2.0 client credentials, password grant, and authorization code + PKCE are supported.
- Tokens are cached per environment and refreshed automatically.
Customization includes the following.
- Custom themes and keybindings.
A few keys that make Resterm feel “native” quickly:
-
Pane focus & layout
Tab/Shift+Tab- move focus between sidebar, editor, and response.g+r- jump to Requests (sidebar).g+i- jump to Editor.g+p- jump to Response.g+h/g+l- adjust layout:- When the left pane (sidebar) is focused: change sidebar width.
- Otherwise: change editor/response split.
g+v/g+s- toggle response pane between inline and stacked layout.g+1,g+2,g+3+ minimize/restore sidebar, editor, response.g+z/g+Z- zoom the focused pane / clear zoom.
-
Environments & globals
Ctrl+E- switch environments.Ctrl+G- inspect captured globals.
-
Working with responses
Ctrl+V/Ctrl+U- split the response pane for side-by-side comparison.- When response pane is focused:
Ctrl+Shift+Corg y- copy the entire Pretty/Raw/Headers tab to the clipboard (no mouse selection needed).
Tip
If you only remember three shortcuts…
Ctrl+Enter- send requestTab/Shift+Tab- switch panesg+p- jump to response
Linux / macOS (Homebrew)
brew install restermNote
Homebrew installs should be updated with Homebrew (brew upgrade resterm). The built-in resterm --update command is for binaries installed from GitHub releases or install scripts.
Linux / macOS (Shell script)
Important
Pre-built Linux binaries depend on glibc 2.32 or newer. If you run an older distro, build from source on a machine with a newer glibc toolchain or upgrade glibc before using the release archives.
curl -fsSL https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.sh | bashor with wget:
wget -qO- https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.sh | bashWindows (PowerShell)
iwr -useb https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.ps1 | iexThese scripts detect your architecture, download the latest release, and install the binary.
Note
The manual install helper uses curl and jq. Install jq with your package manager (brew install jq, sudo apt install jq, etc.).
Linux / macOS
# Detect latest tag
LATEST_TAG=$(curl -fsSL https://api.github.com/repos/unkn0wn-root/resterm/releases/latest | jq -r .tag_name)
# Download the matching binary (Darwin/Linux + amd64/arm64)
curl -fL -o resterm "https://github.com/unkn0wn-root/resterm/releases/download/${LATEST_TAG}/resterm_$(uname -s)_$(uname -m)"
# Make it executable and move it onto your PATH
chmod +x resterm
sudo install -m 0755 resterm /usr/local/bin/restermWindows (PowerShell)
$latest = Invoke-RestMethod https://api.github.com/repos/unkn0wn-root/resterm/releases/latest
$asset = $latest.assets | Where-Object { $_.name -like 'resterm_Windows_*' } | Select-Object -First 1
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile resterm.exe
# Optionally relocate to a directory on PATH, e.g.:
Move-Item resterm.exe "$env:USERPROFILE\bin\resterm.exe"go install github.com/unkn0wn-root/resterm/cmd/resterm@latestresterm --check-update
resterm --updateThe first command reports whether a newer release is available. The second downloads and installs it (Windows users receive a staged binary to swap on restart).
- Environments are JSON files (
resterm.env.json) discovered in the request directory, workspace root, or CWD. Dotenv files (.env,.env.*) are opt-in via--env-fileand are single-workspace. Prefer JSON when you need multiple environments in one file. - Flags you probably reach for most are
--workspace,--file,--env,--env-file,--timeout,--insecure,--follow,--proxy,--recursive,--from-curl,--from-openapi, and--http-out. - Config is stored at
$HOME/Library/Application Support/resterm,%APPDATA%\resterm, or$HOME/.config/restermand can be overridden withRESTERM_CONFIG_DIR.
You can export a workspace into a Git-friendly Resterm bundle. The exported bundle always includes a manifest.json with checksums, so imports can verify file integrity before writing anything.
When Resterm sees resterm.env.example.json in your workspace, it includes that file as-is. If only resterm.env.json exists, Resterm generates resterm.env.example.json automatically and replaces values with REPLACE_ME placeholders so secrets are not exported.
resterm collection export \
--workspace ./my-api \
--out ./shared/my-api-bundle \
--recursive \
--name "my-api-v1"resterm collection import \
--in ./shared/my-api-bundle \
--workspace ./my-local-apiIf you want to preview actions first, you can run:
resterm collection import \
--in ./shared/my-api-bundle \
--workspace ./my-local-api \
--dry-runIf files already exist and should be replaced intentionally, add --force.
Paste a curl command into the editor and press Ctrl+Enter to convert it into a structured request. Resterm understands common flags, merges repeated data segments, and keeps multipart uploads intact.
curl \
--compressed \
--url "https://httpbin.org/post?source=resterm&case=multipart" \
--request POST \
-H "Accept: application/json" \
-H "X-Client: resterm-dev" \
--user resterm:test123 \
-F file=@README.md \
--form-string memo='Testing resterm inline curl
with multiline value' \
--form-string meta='{"env":"test","attempt":1}'If you copied the command from a shell, prefixes like sudo or $ are ignored automatically.
RestermScript (RTS) is a small expression language built specifically for Resterm. Because it targets Resterm features directly, it can evolve alongside Resterm and stay symbiotic with the request format, workflows, and directives. JavaScript hooks are still available when you want them, but RTS is the default because it is readable, predictable, and focused on Resterm’s domain.
Quick example (RTS module + request):
// rts/helpers.rts
module helpers
export fn authHeader(token) {
return token ? "Bearer " + token : ""
}
# @use ./rts/helpers.rts
# @when env.has("feature")
# @assert response.statusCode == 200
GET https://api.example.com/users/{{= vars.get("user") }}
Authorization: {{= helpers.authHeader(vars.get("auth.token")) }}Full reference: docs/restermscript.md.
Resterm supports client credentials, password grant, and authorization code + PKCE. For auth code flows, it opens your system browser, spins up a local callback server on 127.0.0.1, captures the redirect, and exchanges the code automatically. Tokens are cached per environment and refreshed when they expire. Docs: docs/resterm.md#oauth-20-directive and _examples/oauth2.http.
Chain requests with @workflow and @step, pass data between steps, and add lightweight JS hooks where needed. Docs + sample: docs/resterm.md#workflows-multi-step-workflows and _examples/workflows.http.
Run the same request across environments with @compare or --compare, then diff responses side by side with g+c. Docs: docs/resterm.md#compare-runs.
Add @trace with budgets to capture DNS, connect, TLS, TTFB, and transfer timings. Resterm visualizes overruns and can export spans to OpenTelemetry. Docs: docs/resterm.md#timeline--tracing.
Use @websocket with @ws steps or @sse to script and record streams. The Stream tab keeps transcripts and includes an interactive console. Docs: docs/resterm.md#streaming-sse--websocket.
Resterm supports unary and streaming calls with transcripts, metadata, and body expansion for gRPC files. Docs: docs/resterm.md#grpc.
Convert OpenAPI 3 specs into Resterm-ready .http collections from the CLI with --from-openapi. Docs: docs/resterm.md#importing-openapi-specs.
Export a portable Resterm-native bundle with resterm collection export and import it into another workspace with resterm collection import. Docs: docs/resterm.md#collection-sharing.
Convert curl commands into .http files from the CLI with --from-curl. Docs: docs/resterm.md#importing-curl-commands.
Route HTTP, gRPC, WebSocket, and SSE traffic through bastions with @ssh profiles. Docs: docs/resterm.md#ssh-tunnels and _examples/ssh.http.
Route HTTP, gRPC, WebSocket, and SSE traffic through Kubernetes with @k8s profiles targeting pods/services/deployments/statefulsets. Docs: docs/resterm.md#kubernetes-port-forwards and _examples/k8s.http.
Customize colors and keybindings via themes/*.toml and bindings.toml or bindings.json under the config directory. Docs: docs/resterm.md#theming and docs/resterm.md#custom-bindings.
The full reference, including request syntax, metadata, directive tables, scripting APIs, transport settings, and advanced workflows, lives in docs/resterm.md.






