
RESTMan
RESTMan is a keyboard-driven TUI HTTP client for the terminal. Compose and
send HTTP(S) requests interactively — or script one-shot requests from the
command line — without leaving your shell.
[[TOC]]
Features
- All HTTP methods — GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT,
PATCH, or any custom verb
- Interactive TUI — full-screen Brick-based
terminal UI
- Oneshot mode —
--oneshot URI prints the response body to stdout and
exits (scriptable like curl)
- Quick Request mode — pass a URI on the command line to pre-populate the
TUI and fire the request immediately
- Syntax-highlighted responses — MIME-type-aware, pygments colour theme via
Skylighting
- Bi-directional scroll — arrow keys, Vi/Vim keys (
hjkl), Page Up/Down,
and mouse wheel
- Custom headers — add, edit, enable, or disable individual headers in a
table with horizontal scroll
- Default headers toggle — view and toggle the wreq default headers
(
Accept-Encoding, User-Agent, …)
- Request payloads — provide a body inline (
--payload) or from a file
(--payload-file)
- TLS / HTTPS — via
http-client-tls; 30-second timeout guards against
captive portals and slow proxies
- Shell completions — HTTP method names auto-complete via
optparse-applicative
TUI Preview
Header(s) Payload Session Help
================================================================================
╭── Verb ──╮ ╭─────────────────── URL to Query? ──────────────────────────╮
│ GET ▼│ │ https://api.example.com/v1/items │
╰──────────╯ ╰────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────╮
│ [X] Use Default Headers │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Accept-Encoding: gzip, deflate, br │ │
│ │ User-Agent: Haskell wreq-0.5.4.1/0.0.0.0 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
╰──────────────────────────────────────────────────────────────────────────╯
╭─ Active ──╮╭────────────── Name ─────────────╮╭──────── Value ───────────╮
│ [X] ││ Authorization ││ Bearer my-token │
│ [ ] ││ X-Request-ID ││ deadbeef-cafe │
╰───────────╯╰─────────────────────────────────╯╰───────────────────────────╯
[+ Add Custom Header]
╭────────────────────────── Response Body ──────────────────────────────╮▲
│ { │ │
│ "items": [ │▓│
│ { "id": 1, "name": "widget" } │ │
│ ] │▼│
╰───────────────────────────────────────────────────────────────────────╯◄▓►
| Platform |
Status |
| Linux |
✓ Fully supported |
| macOS — Intel |
✓ Supported |
| macOS — Apple Silicon (M1 / M2 / M3) |
✓ Supported (requires llvm, see below) |
| Windows via WSL2 + Debian |
✓ Supported — recommended Windows path |
| Windows native |
⚠ Experimental — supported since Brick 2.0 / vty 6.0 via vty-windows, but builds have been unreliable; see Known Limitations |
Prerequisites
| Tool |
Version |
Notes |
| GHC |
9.10.x |
Managed automatically by Stack |
| Stack |
any recent |
Primary build tool |
| llvm |
— |
macOS Apple Silicon only — brew install llvm |
Stack will download and configure the correct GHC version (via Stackage
LTS 24.38) on first run.
Quick Start
# 1. Clone the repository
git clone https://gitlab.com/krakrjak/restman.git
cd restman
# 2. Set up the compiler (once — downloads GHC 9.10.x if needed)
stack setup
# 3. Build RESTMan and all dependencies
stack build
# 4. Launch the TUI
stack exec restman
First build resolves and compiles all Haskell dependencies, which can
take several minutes.
Installation
To install the restman binary to ~/.local/bin:
stack install
Add ~/.local/bin to your PATH so you can run restman directly:
# Add to ~/.bashrc, ~/.zshrc, etc.
export PATH="$HOME/.local/bin:$PATH"
RESTMan is also listed on Hackage
as a package reference.
Usage
Modes of Operation
| Mode |
How to invoke |
Description |
| Interactive TUI |
restman |
Full-screen TUI — compose and send requests interactively |
| Quick Request |
restman URI |
TUI launches with URI pre-filled; request fires immediately |
| Oneshot |
restman --oneshot URI |
Prints response body to stdout and exits — no TUI |
Command-line Reference
Usage: restman [--help] [-m|--method METHOD]
[--no-default-headers | --default-headers]
[-h|--custom-header NAME_VALUE]
[--payload PAYLOAD | --payload-file PATHNAME]
[--oneshot] [URI]
| Flag |
Short |
Default |
Description |
--help |
|
|
Show help and exit |
--method METHOD |
-m |
GET |
HTTP method / verb |
--no-default-headers |
|
off |
Send only custom headers (suppress wreq defaults) |
--default-headers |
|
on |
Append custom headers after wreq defaults |
--custom-header NAME_VALUE |
-h |
— |
Add a Name:Value header (repeatable) |
--payload PAYLOAD |
|
— |
Inline request body (UTF-8) |
--payload-file PATHNAME |
|
— |
Load request body from a file |
URI |
|
— |
Target URL (positional, optional) |
--oneshot |
|
off |
Non-interactive one-shot mode (requires URI) |
--custom-header format: Name:Value — the first colon separates the header
name from its value. The flag may be repeated to supply multiple headers.
Examples
# Open the TUI (no arguments)
restman
# Open the TUI pre-loaded with a URL (request fires immediately)
restman https://httpbin.org/get
# One-shot GET — print the response body to stdout
restman --oneshot https://httpbin.org/get
# One-shot POST with a JSON payload
restman --oneshot -m POST \
-h 'Content-Type:application/json' \
--payload '{"key":"value"}' \
https://httpbin.org/post
# PUT with a binary payload file, suppressing default headers
restman -m PUT \
--no-default-headers \
-h 'Content-Type:application/octet-stream' \
--payload-file ./data.bin \
https://example.com/upload
TUI Keybindings
Global
| Key |
Action |
Esc / Ctrl+Q |
Quit RESTMan |
Tab |
Move focus to the next widget |
Shift+Tab |
Move focus to the previous widget |
Enter (URL editor focused) |
Send the HTTP request |
| Key |
Action |
↓ (on Method field) |
Open the method selector popup |
↑ / ↓ |
Navigate the method list |
Enter |
Confirm selection and close the popup |
Esc |
Close the popup without changing the method |
| Key |
Action |
Space on [+ Add Custom Header] |
Add a new empty header row |
Space on a header checkbox |
Enable / disable that header |
Tab into a Name or Value cell |
Begin editing the cell |
← / → |
Scroll cell content horizontally |
| Key |
Action |
Tab to [X] Use Default Headers |
Move focus to the toggle |
Space |
Toggle default headers on / off |
Response Viewport
| Key |
Action |
↓ / j |
Scroll down one line |
↑ / k |
Scroll up one line |
→ / l |
Scroll right one column |
← / h |
Scroll left one column |
Page Down |
Scroll down one page |
Page Up |
Scroll up one page |
| Mouse scroll |
Scroll three lines up / down |
Building from Source
Linux / Debian (and Windows WSL2)
Install the required system packages:
apt install haskell-stack libtinfo-dev libz1g-dev
Upgrade to the latest Stack release, then set up the compiler and build:
stack upgrade # may prompt for sudo
stack setup # downloads GHC 9.10.x
stack build
macOS — Intel
stack setup
stack build
macOS — Apple Silicon (M1 / M2 / M3)
Install ghcup and LLVM:
brew install llvm
Export the LLVM paths (add these to your shell profile):
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
export LDFLAGS="-L/opt/homebrew/opt/llvm/lib"
export CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
Then build with the aarch64 target:
stack --arch aarch64 --system-ghc build
Windows
WSL2 (recommended): Use WSL2 with a Debian distribution and follow the
Linux / Debian steps above.
Windows native (experimental): Native Windows support was introduced in
vty 6.0 / Brick 2.0 via
vty-windows, which
RESTMan picks up transitively through Brick. However, vty-windows has a
tightly pinned Win32 dependency and build failures have been reported.
If you want to attempt a native build, install
GHCup for Windows, then:
stack setup
stack build
Please report any success or failure in the
issue tracker.
Running Tests
stack test
The test suite uses Tasty with
HUnit unit tests, Hedgehog property tests, and an in-process HTTP echo server
for integration tests.
Known Limitations
- Windows native (experimental) — native Windows support was added in
vty 6.0 and
Brick 2.0 via the
vty-windows backend.
However, vty-windows has a tightly pinned Win32 dependency and has had
reported build failures. WSL2 + Debian remains the most reliable Windows
path until vty-windows stabilises.
- 8 KB header line limit —
http-client enforces a hard 8 KB limit per
response header line. Sites with very large headers (e.g. slashdot.org's
Content-Security-Policy) will produce an OverlongHeaders exception.
- Captive portals — the 30-second response timeout guards against infinite
hangs, but portal authentication pages are not navigable from the TUI.
Contributing
Bug reports and feature requests:
gitlab.com/krakrjak/restman/issues
Before submitting a merge request, please ensure:
stack build passes with no warnings
stack test is green
- Code passes
hlint and is formatted with stylish-haskell
- pre-commit hooks are installed
(
pre-commit install)
License
BSD 2-Clause — © Zac Slade, Boyd Stephen Smith Jr.