Changelog
Every release, what actually shipped in it, and what did not. Builds are on the releases page.
The first public build. A desktop API client that stores everything as files in a directory you choose, sends HTTP, GraphQL and gRPC, and asks you for nothing.
Requests
- HTTP requests: method, URL, headers, body, with the response body, headers, status, elapsed time and size. Non-2xx responses render as results; only transport failures are errors.
- GraphQL requests: a query plus a JSON variables document, posted as a GraphQL body. Invalid variables JSON fails loud instead of silently sending an empty object.
- gRPC requests:
.protofiles compiled in-process (noprotocneeded), service and method listing, unary calls, and ASCII metadata. Streaming methods are listed as disabled and refuse loudly. No server reflection. - Auth as a first-class field:
none,bearer,basic, andapikeyplaced in a header or a query parameter.
Storage
- Collections, folders and requests stored as plain text files under a workspace directory —
.httpfor HTTP and GraphQL,.grpcfor gRPC. Folders are directories; requests are files; renames are file renames. - Multiple workspaces, switchable from the app, with the registry kept out of the workspace itself.
- Atomic writes and path confinement — a request path cannot escape its collection directory, and unparseable files are reported rather than silently dropped.
- Environments as one TOML file each, with
{{var}}interpolation across URL, headers, body, auth fields, GraphQL query and variables, and gRPC message and metadata. Unresolved variables are a hard error.
Tests
- Declarative assertions stored as data:
status(eq/ne/lt/gt),jsonwith a JSONPath (eq/ne/exists/absent/contains/matches/lt/gt/len),header(exists/absent/eq/contains/matches) andduration(lt/gt). - Captures from
status,header.<Name>orbody.$.<jsonpath>into a variable, with arun/session/persistscope recorded on each. - Pre-request and post-response scripts running a
pm.*subset in a sandboxed QuickJS engine embedded in the Rust core, with memory and wall-clock limits. No Node APIs, no filesystem, no network, no timers — every one of them refuses with an explanation.
Moving in and out
- Postman collection import, with a report listing what was imported, what was skipped and why, and which requests carry warnings.
- Single-file bundle export of a whole workspace, and import of the same.
Where it runs
- Desktop builds for macOS, Windows and Linux, built on Tauri 2 with the Rust core doing the networking.
- The same client in the browser at /app, from the same codebase — collections stored in the browser, and on Chromium a real local folder via the File System Access API. Browsers enforce CORS on the requests a page makes and only expose safelisted response headers unless the server says otherwise; the desktop app has no such restriction, and we do not proxy traffic.
- gRPC runs in both, by different routes: the desktop app speaks native gRPC over tonic, and the browser speaks gRPC-Web — which needs the service to sit behind a gRPC-Web layer such as
tonic-webor Envoy. Native gRPC in a tab is impossible, not merely unbuilt: it needs HTTP/2 trailers no browser hands to a page. Both platforms compile your.protofiles with the same Rust code, the browser running it as WebAssembly.
Not in this release
So you can plan accordingly: no cloud sync, no team workspace UI, no mock servers, no API monitoring, no WebSocket or SSE, no persisted request history, no code generation, and no OAuth 2 flow handling. The mandalo command line runner and the VS Code extension are in development and are not part of this build.
The comparison with Postman spells out the gaps, and the docs cover what is here.