Skip to content

Latest commit

 

History

28 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

htx

A local-first, git-friendly API client — a Postman/Bruno alternative with a Rust core, a full CLI, and a web UI.

htx UI

A workspace is a plain directory of pretty-printed JSON files: one file per request, one per environment, one manifest. You version it with git like any other source tree. There is no cloud, no account, and no telemetry.

Features

  • Local-only, git-friendly storage — everything lives in your workspace directory as camelCase JSON, one file per request, so diffs and merges stay small and reviewable.
  • Full CLI — htx covers the whole product: init, import, run, environments, secrets, history, export, git, and serving the UI. Exit codes are script-friendly (0 ok, 1 test failures, 2 error) and --json gives machine-readable output.
  • JavaScript tests, Postman-style — write htx.test("...", () => htx.response.to.have.status(200)) in a Monaco editor with htx autocompletion; they run in the Rust core (no Node), so the UI and htx run execute the same script. htx.environment.set writes through to the environment file, which is how you chain a login token into later requests. See docs/SCRIPTING.md.
  • Environments — named variable sets with {{variable}} interpolation in URLs, params, headers, bodies, and auth; one environment is active at a time, or override per run.
  • Request history — every execution is appended to .http/history.jsonl with the resolved request, response, timing, and test results; browse it from the UI or htx history.
  • OpenAPI v3 import/export — import a JSON or YAML document into a collection (one request per operation, parameters and body skeletons included) and export any collection back to OpenAPI 3.0; the round-trip is stable.
  • Tabbed UI — a VS-Code-like single page (Vite + React + Joy UI) with request tabs, dirty indicators, keyboard shortcuts, response viewer, environments, history, secrets, and a git panel.
  • Secret management, never committed — secrets live only in .http/secrets.json (gitignored by htx init, 0600 on unix), are referenced as {{secret.NAME}}, are masked in every listing, and are redacted from history before anything touches disk.

Two applications, packaged separately

htx ships as two independent downloads. Neither needs the other; take whichever fits, or both.

What it is UI
htx-desktop The desktop app — the UI in its own window. Compiled into the binary; the API runs in the same process, so nothing listens on a port.
htx The command line tool, for scripting and CI. htx serve hosts the UI in a browser over 127.0.0.1.

Both are built for macOS (universal) and Windows (x64). See scripts/README.md for how the artifacts are assembled.

Quickstart

Build once (Rust 1.94+, Node 22+):

# build the web UI — both binaries need it
cd ui && npm install && npm run build && cd ..

# the desktop app: opens a window, scaffolds ~/htx on first run
cargo run -p htx-desktop

# or the CLI, serving the UI to a browser on http://127.0.0.1:7878
cargo run -p htx -- init my-api
cargo run -p htx -- -C my-api serve

htx-desktop takes no arguments; set HTX_WORKSPACE to choose a workspace directory other than ~/htx, and HTX_DEVTOOLS to enable the webview inspector.

Or stay entirely in the terminal:

cargo install --path crates/htx   # or use target/debug/htx

htx init my-api && cd my-api                # scaffold workspace + git repo
htx import openapi ../examples/petstore-expanded.json
htx list                                    # collections & requests tree
htx env set dev baseUrl https://api.example.com
htx secret set API_TOKEN                    # prompts; value stays out of shell history
htx run swagger-petstore/findpets -e dev    # send + run assertions

CLI reference

Global flags: -C/--dir <path> selects the workspace directory (default .); --json switches run and history to machine-readable output.

Command Description
htx init [NAME] Scaffold a workspace (into a NAME directory when given) plus git init and a .gitignore.
htx serve [-p 7878] [--ui-dir DIR] Start the local API server on 127.0.0.1, serving the built UI when available.
htx list Print the collections & requests tree.
htx run <collection>[/<request>] [-e ENV] [--json] Run one request or a whole collection with its tests.
htx run --all [-e ENV] [--json] Run every request of every collection.
htx env list | show <slug> | set <slug> KEY VALUE Inspect and edit environments (set creates the environment when missing).
htx secret list | set NAME [--value V] [--env SLUG] | rm NAME [--env SLUG] Manage secrets; set prompts without echo when --value is omitted.
htx history [--limit N] [--json] / htx history clear Show or clear the execution history.
htx import openapi <file> [--name NAME] Import an OpenAPI v3 document (JSON or YAML) into a new collection.
htx export openapi <collection> [-o out.json] Export a collection as an OpenAPI 3.0 document.
htx git status | commit -m MSG | log [--limit N] Git shortcuts for the workspace repository.

Tests

Tests are JavaScript, with Postman's API, written in the Tests tab (Monaco, with htx autocompletion) or straight into the request's JSON file:

htx.test("Status code is 200", function () {
  htx.response.to.have.status(200);
});

htx.test("Response is a list of pets", function () {
  const body = htx.response.json();
  htx.expect(body.pets).to.be.an("array").that.is.not.empty;
  htx.expect(body.pets[0]).to.have.property("name");
});

// Chain requests: saved to the active environment, used as {{token}} later.
htx.environment.set("token", htx.response.json().token);

They run in the Rust core on Boa — no Node, no browser — so htx run in CI executes exactly what the UI does, and exits 1 when a test fails. Secrets are never visible to a script and are redacted from its output. docs/SCRIPTING.md is the full reference, including what is deliberately not supported.

Workspace layout

my-api/
  http.json                  # workspace manifest {name, version, activeEnvironment}
  collections/
    petstore/
      collection.json           # {name, description}
      requests/
        list-pets.json          # one file per request: method, url, params,
                                # headers, body, auth, testScript, docs
  environments/
    dev.json                    # {name, variables: [{name, value, enabled}]}
  .http/                     # gitignored — never committed
    secrets.json                # secret values (0600 on unix)
    history.jsonl               # one execution record per line, append-only
  .gitignore                    # created by `htx init`, contains `.http/`

Architecture

  • crates/http-core — models, storage, interpolation, secrets, history, HTTP engine + assertions, the JavaScript test sandbox (docs/SCRIPTING.md), OpenAPI import/export, git (docs/DESIGN.md).
  • crates/http-server — axum REST API and static hosting for the built UI (docs/API.md).
  • crates/htx — the htx binary: CLI plus htx serve.
  • crates/htx-desktop — the htx-desktop binary: the desktop app. A native window hosting the system webview, with ui/dist compiled in and the http-server router dispatched in-process — no local server, no port, no browser.
  • ui/ — Vite + React + TypeScript + Joy UI single-page app (docs/UI.md), shared by both binaries.

Development

cargo test --workspace                            # unit + integration tests (core, server, CLI, desktop)
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --all --check

cd ui
npm install
npm test -- --run                                 # vitest
npm run build                                     # tsc (strict) + vite build → ui/dist
npm run dev                                       # dev server, proxies /api → 127.0.0.1:7878

The desktop app embeds ui/dist at compile time, so re-run npm run build before cargo build -p htx-desktop to pick up UI changes (its build.rs makes cargo notice). On Linux, building it needs the GTK webview stack: libgtk-3-dev libsoup-3.0-dev libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev.

Tests spin up in-process HTTP servers on ephemeral localhost ports; nothing depends on external network access.

License

MIT (declared in the workspace Cargo.toml).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages