Local-first API client + mock server

Stub it. Ship it.

StubHouse is the desktop API client that takes mocking seriously. Native, offline, file-based — built for the developer who has to ship before the API exists.

Available for macOS, Linux, and Windows.

Native Rust core Offline workspaces Mock server included
StubHouse — my-project
Mock rule priority 30
matcher:
  method: GET
  path: /users/:id
response:
  status: 200
  body:
    id: "{{params.id}}"
scenarios:
  outage: 503
  slow: delay 900ms
Response matched happy_path
// workspace ready
base_url = http://127.0.0.1:4000
env      = mock
status 200 route exact > :param > * JUnit ready

One workspace for real requests, environments, imports, cURL export, and local mock rules.

Two tools. One binary.

A request client and a mock server, both first-class.

Other API clients bolt on mocks as a paid afterthought or a separate process. StubHouse pairs the daily request workflow with a headless local mock runtime, a desktop server panel, live logs, scenarios, and test-runner hooks.

Request — production

GET · https://api.example.com/users

200 OK · 132 ms
{
  "items": [{ "id": "u1", "name": "Ada" }]
}
Mocks — rules
  • GET /users exact
  • POST /users exact
  • GET /users/:id param

Routes are matched by priority: exact, params, wildcards, then catch-all.

Source of truth

Your API definitions live in a folder you own.

No proprietary database. No cloud account required. A workspace is a `.stubhouse/` directory of YAML files: requests, mock rules, environments, scripts. Commit it to git. Diff it in PRs. Move it between machines with `cp -r`. The tool builds on top of files; the files outlive the tool.

.stubhouse/collections/users/get-user.yaml yaml
id: req_get_user
name: "Get User by ID"
description: |
  Retrieves a single user by their unique ID.
method: GET
url: "{{base_url}}/users/{{user_id}}"
headers:
  - key: Authorization
    value: "Bearer {{auth_token}}"
    enabled: true
auth:
  type: bearer
  token: "{{auth_token}}"
tags:
  - users
  - read

The mock server

The mock foundation is in the binary now.

YAML rules

Mock rules live next to collections, parse in Rust, and are served from the same core used by the desktop app. The current matcher handles methods, exact paths, path params, wildcards, and catch-alls.

.stubhouse/collections/users/mocks/get-user.yaml yaml
matcher:
  method: GET
  path: /users/:id
response:
  status: 200
  headers:
    content-type: application/json
  body:
    id: "{{params.id}}"
    name: Ada

Headless serve

`stubhouse serve` starts the local mock runtime without opening the app. Frontend tests can point at `127.0.0.1` while the backend is still being written.

terminal bash
# Create a workspace, validate it, serve mocks
stubhouse init acme-api
stubhouse validate
stubhouse envs
stubhouse import openapi ./openapi.yaml
stubhouse scenario list

stubhouse serve --port 4000
curl http://127.0.0.1:4000/users/usr_1
curl -X POST http://127.0.0.1:4000/users -d '{"name":"Ada"}'
stubhouse export curl collections/users/get-user.yaml --env dev

Next in mocks

The runtime now covers the parts that make mocks useful during product work: scenarios, logs, hot reload, control APIs, faults, passthrough, recording, and stateful resources.

  • Named scenarios with CLI and desktop activation
  • Mock server panel with on/off, port picker, and live request log
  • Hot reload for mock YAML, resources, and recording config
  • Control API under /__mirage/*
  • Fault injection and selective passthrough
  • Recording mode, scrub rules, fixtures, and stateful resources

Available now

The daily API client path is already covered.

Phase 1 is complete: requests, auth composition, environments, interpolation, history, import, cURL export, and the CLI. The mock runtime now builds on top of that same file-based workspace with scenarios, hot reload, live logs, faults, passthrough, recording, resources, and control routes.

HTTP runtime

HTTP/1.1, HTTP/2, TLS, auth composition, and JSON/text/form bodies.

request engine: reqwest + rustls

Environments

Workspace environment files, variable resolution, and inline resolved-URL preview.

url: "{{base_url}}/users/{{user_id}}"

Import / export

Postman and OpenAPI 3 import, plus cURL and OpenAPI YAML export.

stubhouse import openapi ./openapi.yaml

Headless mocks

Embedded Hyper mock server with YAML rules, hot reload, request logs, and control routes.

stubhouse serve --port 4000

Route matcher

Exact paths, path params, wildcards, catch-alls, method matching, and script conditions.

GET /users/:id when params.id != ""

Tests

Rhai response assertions with CLI and desktop test runs, including JUnit XML output.

stubhouse test --env ci --junit results.xml

Automation path

A CLI first, then scripting on top.

The CLI can initialize, validate, inspect environments, import Postman or OpenAPI, export cURL or OpenAPI YAML, serve mocks, switch scenarios, and run Rhai assertions with optional JUnit output.

terminal bash
# Create a workspace, validate it, serve mocks
stubhouse init acme-api
stubhouse validate
stubhouse envs
stubhouse import openapi ./openapi.yaml
stubhouse scenario list

stubhouse serve --port 4000
Test runner

Rhai assertions · shipped

JUnit XML output · shipped

Mock rule conditions · shipped

It's a binary

stubhouse serve and ship.

The same mock engine can run from the command line. Spin up local API responses before your app tests, point the frontend at `127.0.0.1`, and keep backend availability out of the loop.

ci.sh bash
# CI: serve local mocks, then run your app tests
stubhouse serve --port 4000 &
MOCK_PID=$!

npm test

kill $MOCK_PID

Honestly

Where StubHouse fits.

A direct comparison with the tools you already know. We ship the embedded mock as part of the product, not as an upsell.

StubHouse vs Postman, Insomnia, Bruno, and Yaak

Local-first workspaces, files on disk, native app shell, and the mock server roadmap in one focused table.

Compare with other apps
StubHousePostmanInsomniaBrunoYaak
Local-first (no account)
Files as source of truth
Embedded mock server
Stateful mocks
Scenario switching
Recording mode
Fault injection
Mock control API
CI / headless mode
OpenAPI schema validationimport/export
Native binary (no Electron)
Scripting languageRhaiJS (V8)JS (V8)JS (V8)
Free and open source

Local-first (no account)

StubHouse Postman Insomnia Bruno Yaak

Files as source of truth

StubHouse Postman Insomnia Bruno Yaak

Embedded mock server

StubHouse Postman Insomnia Bruno Yaak

Stateful mocks

StubHouse Postman Insomnia Bruno Yaak

Scenario switching

StubHouse Postman Insomnia Bruno Yaak

Recording mode

StubHouse Postman Insomnia Bruno Yaak

Fault injection

StubHouse Postman Insomnia Bruno Yaak

Mock control API

StubHouse Postman Insomnia Bruno Yaak

CI / headless mode

StubHouse Postman Insomnia Bruno Yaak

OpenAPI schema validation

StubHouse import/export Postman Insomnia Bruno Yaak

Native binary (no Electron)

StubHouse Postman Insomnia Bruno Yaak

Scripting language

StubHouse Rhai Postman JS (V8) Insomnia JS (V8) Bruno JS (V8) Yaak

Free and open source

StubHouse Postman Insomnia Bruno Yaak

Sourced from public information as of 2026-05-21. Updated when competitors ship. Corrections welcome — open a PR.

Under the hood

Native binary. No Electron.

Tauri 2 shell. Rust core. `hyper` HTTP runtime. `rustls` for TLS. Embedded mock server runs in a Tokio task in the same process as the UI. Numbers below stay illustrative until published release artifacts include measured install sizes.

StubHouse
~25 MB
Insomnia
~110 MB
Postman
~350 MB

Cold-start bar uses the same discipline — measure before launch, publish with releases.

It's free. It's open.

MIT licensed.

StubHouse is open source under the MIT License. No usage tracking. No telemetry without an explicit opt-in. No "Pro" features held hostage. The full source — desktop app, CLI, and core libraries — is on GitHub. PRs welcome.

terminal bash
$ git clone https://github.com/stubhouse/stubhouse
$ cd stubhouse && cargo build --release
   Finished release [optimized] target(s) in 2m 14s

Ready when the API isn't

Run real requests and local mocks from one native app.

Free, open source, and available for macOS, Linux, and Windows.