FauxRPC accelerates development and testing by generating fake implementations directly from Protobuf and OpenAPI schemas. A single server can expose gRPC, gRPC-Web, Connect, and HTTP/REST services without writing an implementation.
- Faster Development & Testing: Work independently without relying on fully functional backend services.
- Isolation & Control: Test frontend components in isolation with controlled fake data.
- Multi-Protocol Support: Supports multiple protocols (gRPC, gRPC-Web, Connect, and REST).
- OpenAPI Support: Serve OpenAPI operations, validate requests, generate schema-shaped bodies and headers, and browse interactive API documentation.
- Prototyping & Demos: Create prototypes and demos quickly without building the full backend. Fake it till you make it.
- API Stubs: Define static or dynamic API responses with powerful stubs featuring CEL expressions for precise behavior control. Stubs can be defined using config files or dynamically at runtime.
- Improved Collaboration: Bridge the gap between frontend and backend teams.
- Plays well with others: Generated data follows OpenAPI schema constraints and tries to follow any protovalidate constraints defined in Protobuf schemas.
- Request Validation: Validate HTTP requests against OpenAPI operations and RPC messages with protovalidate.
See the documentation website for more!
go install github.com/sudorandom/fauxrpc/cmd/fauxrpc@v0.28.0Binaries are built for several platforms for each release. See the latest ones on the releases page.
The core command is fauxrpc run, which starts the server based on your Protobuf or OpenAPI schema. You can combine flags to configure the server on startup.
For example, this command starts the server with a specific schema, loads a stub for a method, and enables the dashboard:
fauxrpc run --schema=buf.build/connectrpc/eliza --stubs=example/stubs.eliza --dashboardYou must provide schemas so FauxRPC knows which services to fake. Protobuf descriptors and OpenAPI specifications use the same --schema option, and you can mix and match sources.
fauxrpc run --schema=service.binpbfauxrpc run --schema=buf.build/bufbuild/elizafauxrpc run --schema=openapi.yamlOpenAPI specifications can be YAML or JSON files, URLs, or directories containing specifications. See OpenAPI Support for a complete example.
fauxrpc run --schema=service.binpb --schema=openapi.yamlFauxRPC can serve OpenAPI operations alongside Protobuf services. It detects OpenAPI YAML and JSON documents passed through the same --schema option used for Protobuf descriptors.
For an operation without a matching stub, FauxRPC:
- Matches the HTTP method, server base path, and templated path.
- Validates path parameters, query parameters, headers, and request bodies against the operation.
- Selects a successful response, preferring
200, then201, then the default or first declared response. - Generates response bodies from schemas, including examples, defaults, enums, constraints, formats, arrays, objects,
allOf,oneOf,anyOf, and recursive references. - Generates response headers declared by the selected OpenAPI response.
Explicit OpenAPI examples and defaults are preserved. Other generated values vary between requests by default. Use --static-seed to make unstubbed OpenAPI and Protobuf responses deterministic:
fauxrpc run --schema=openapi.yaml --static-seedThe repository includes a locally runnable adaptation of the canonical Swagger Petstore OpenAPI 3.0 specification, plus several conditional stubs:
fauxrpc run \
--schema=example/swagger-petstore-openapi.yaml \
--stubs=example/stubs.swagger-petstore.yamlTry the path-parameter and query-parameter stubs:
curl http://127.0.0.1:6660/api/v3/pet/42
curl "http://127.0.0.1:6660/api/v3/pet/findByStatus?status=available"The interactive OpenAPI documentation is available at http://127.0.0.1:6660/fauxrpc/openapi-docs/. The served document points its primary server URL at FauxRPC while preserving the schema's base path.
OpenAPI stubs can target an operationId or an HTTP path and method. Matches can be narrowed using path parameters, query parameters, headers, or a truthy GJSON path into the request body.
stubs:
- name: The answer to pets, life, and everything
target:
operationId: getPetById
match:
pathParams:
petId: "42"
response:
status: 200
headers:
X-Pet-Mood: existential
body:
id: 42
name: Deep Thought
photoUrls:
- https://fauxrpc.local/pets/deep-thought.jpg
status: availableLoad the file with --stubs:
fauxrpc run --schema=openapi.yaml --stubs=openapi-stubs.yamlWhile FauxRPC generates fake data by default, stubs let you define specific, predictable responses for RPC and OpenAPI operations. This is useful for testing particular scenarios.
You can load a single stub file or an entire directory of them.
Add --only-stubs to disable generated fallback responses. An OpenAPI operation without a matching stub returns HTTP 501 Not Implemented; Protobuf RPCs return an empty response message.
fauxrpc run --schema=eliza.binpb --stubs=example/stubs.eliza/say.jsonfauxrpc run --schema=eliza.binpb --stubs=example/stubs.eliza/FauxRPC can act as an intercepting proxy to ingest real gRPC/Connect traffic and automatically generate stateful, predictable mock profiles (stubs) on disk.
When in proxy mode, FauxRPC forwards incoming requests to an upstream server, captures the request and response payloads, translates them into the stub format, and writes/appends them to files under a structured directory by service/method (e.g., <record-dir>/<service>/<method>.json).
To run FauxRPC in proxy mode:
fauxrpc run --proxy-to=127.0.0.1:8080 --record-dir=stubs/--proxy-to: The address of the upstream gRPC or Connect server to forward requests to.--record-dir: The directory path where the recorded stubs should be saved, structured by service and method.
If the upstream server returns an UNIMPLEMENTED status code (indicating that the endpoint is not yet implemented), FauxRPC will automatically catch the error and fall back to serving a mock response (from stubs or random fake generation). This allows frontend and backend teams to co-develop APIs incrementally.
By default FauxRPC honors the protovalidate rules on a schema, so generated data passes validation. --violate-rules inverts that for testing how clients handle bad data: it takes a probability from 0.0 to 1.0 that any single rule is broken instead of satisfied.
# break every rule that can be broken
fauxrpc run --schema=service.binpb --violate-rules=1.0
# break roughly one rule in five
fauxrpc generate --schema=service.binpb --target=pkg.v1.Response --violate-rules=0.2The same option is available on fauxrpc run, fauxrpc generate, and fauxrpc curl.
The dice are rolled per rule, not per field or per message. A field carrying a single rule is invalid about p of the time; a field carrying three independent rules is invalid about 1-(1-p)Β³ of the time. Because a field can only hold one value, when several of its rules come up at once one of them is picked at random to be the one that breaks β so repeated runs exercise different failure modes: a string with both min_len and pattern is sometimes too short and sometimes malformed. required counts as a rule of its own, broken by leaving the field unset.
A few things are never violated, so a message is not guaranteed to fail validation even at 1.0:
- Fields with no rules, or with
ignore: IGNORE_ALWAYS. - Message-level rules and CEL expressions (
cel,cel_expression), which no single field value can be reasoned about generically. - Rules where no counterexample exists, such as an
int32bounded bygteat the type's minimum.
A message that reserves an extension range lends those field numbers to fields declared elsewhere:
message Event {
string id = 1;
string type = 2;
extensions 100 to 199;
}
extend Event {
string trace_id = 100;
bool sampled = 101;
}Those fields are part of the schema, so FauxRPC fills them in like any other field. Each one gets its own roll, so about half of a message's extensions are set on any given response and no two responses carry quite the same set β an extension is an add-on, and a message where every add-on is present is not what clients see in practice.
In JSON, an extension appears under its full name in brackets:
{
"id": "evt_7f3a91",
"type": "checkout.completed",
"[playground.v1.trace_id]": "b9c14e2d",
"[playground.v1.sampled]": true
}Extensions of the google.protobuf.*Options messages are skipped. Every custom option in a schema is one of those, and they describe a schema rather than carry data.
Stubs may name extensions in the same bracketed form.
FauxRPC includes a handy built-in client, fauxrpc curl, for making requests to your services without needing external tools. It automatically sources the schema to provide a seamless testing experience.
fauxrpc curl --http2-prior-knowledge --schema=buf.build/bufbuild/registryfauxrpc curl --http2-prior-knowledge --schema=buf.build/bufbuild/registry buf.registry.plugin.v1beta1.LabelService/ListLabelsIf no --schema option is provided, server reflection will be used to figure out the type and service information.
fauxrpc curl --http2-prior-knowledge buf.registry.plugin.v1beta1.LabelService/ListLabelsEnhance your FauxRPC experience with the interactive dashboard, providing real-time insights into your server's operations.
To enable the dashboard, simply start FauxRPC with the --dashboard option:
fauxrpc run --schema=service.binpb --dashboard
Access the dashboard in your browser at http://127.0.0.1:6660/fauxrpc.
The dashboard provides:
- π Summary: View overall server statistics.
- π Request Log: Live stream of all incoming requests.
- π Schema Browser: Explore Protobuf schemas loaded into the server.
- π Stubs: Manage and view details of registered stubs.
- π API Documentation: Access generated Protobuf documentation and interactive OpenAPI documentation.
Go to the documentation website for more!


