Hey HN,
Most OpenAPI mock servers I've worked with fall into one of three buckets: they're slow to boot (JVM warmup, Node module resolution), they need Docker just to run, or they return the same hardcoded stub on every request. None of that is great when you just want to unblock frontend work or sketch out an integration against a spec that's still moving.
So I built mock-cli — a single static binary written in Rust that reads any OpenAPI 3 spec (YAML or JSON) and serves schema-aware, dynamic fake data over HTTP. No runtime, no container, no config file.
Repo: https://github.com/wanghao12345/mock-cli
npm: npm install -g @mock-cli/server
What makes it different
- Native Rust binary. Cold start is in the low milliseconds. No JVM, no Node overhead, no Docker pull. You run it, it serves.
-
Dynamic, schema-compliant data — not static stubs. Every request produces different fake data that still honors your schema:
format: emailgives you a realistic email,format: uuidgives you a v4 UUID,enumpicks a valid value,requiredfields are always present,minItems/maxItemsare respected. -
Path-aware. If your route is
/pets/{petId}and the response schema has apetIdfield, the value from the URL is injected into the response (coerced to the schema type). SoGET /pets/123returns{"petId": 123, ...}— consistent with the request context, not random noise. -
Cycle-safe
$refresolution. Recursive schemas are bounded so the server never blows the stack on a self-referencing model. -
Correct status codes out of the box.
200on success,404for unknown paths,405for unsupported methods,501when there's no200response defined. Your client's error handling actually gets exercised. - All HTTP methods wired up. GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD, TRACE.
- Single binary, cross-platform. macOS / Linux / Windows, x64 and arm64. Install via npm (auto-picks the right prebuilt binary) or grab the binary from GitHub Releases. Works offline.
30-second demo
Drop a spec:
openapi: 3.0.3
info:
title: Petstore
version: 1.0.0
paths:
/pets/{petId}:
get:
parameters:
- name: petId
in: path
required: true
schema:
type: integer
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
petId:
type: integer
name:
type: string
vaccinated:
type: boolean
Start the server:
mock-cli swagger.yaml
# ✓ Loaded "swagger.yaml" (1 paths)
# ✓ Listening on 127.0.0.1:3333
Hit it:
curl http://localhost:3333/pets/123
# {"petId":123,"name":"Dr. Margret Kihn","vaccinated":true}
curl http://localhost:3333/pets/456
# {"petId":456,"name":"Sarah Connor","vaccinated":false}
Notice petId echoes the path param, but name and vaccinated are fresh fake data on every call. That's the whole point — your frontend gets a realistic, varying response shape without you hand-writing fixtures.
Install
# npm (recommended — picks the right prebuilt binary for your platform)
npm install -g @mock-cli/server
# or build from source
cargo install --path crates/cli
# or just run it without installing
cargo run --release -- examples/swagger.yaml
Why Rust?
Honestly, because I wanted a tool I could ship as one static binary with no runtime dependency, and because the OpenAPI spec is a big tagged-union-shaped data model that maps cleanly onto Rust enums. The parsing and generation core (crates/core) has no IO — it's pure data transformation — which makes it trivial to test and reuse. The HTTP layer (crates/server) is axum, and the CLI (crates/cli) is clap. Clean three-crate split.
Roadmap
Done: dynamic mocking, path param injection, schema format/enum/required/array bounds, $ref resolution with cycle safety, correct HTTP status codes, configurable bind host, graceful shutdown.
Planned: hot reload on spec change, request validation against the spec, custom faker rules via config, multi-spec composition.
Try it
npm install -g @mock-cli/server
mock-cli examples/swagger.yaml
Repo + full docs: https://github.com/wanghao12345/mock-cli
Happy to hear feedback — especially on the faker behavior (what formats/enums you'd like better coverage for) and whether hot-reload or request validation should land first. Issue threads are open.
MIT licensed. Written in Rust 1.85+.
Top comments (0)