Languages: English | 简体中文
The fastest and most reliable gRPC mock server for testing and development.
GripMock creates a mock server from your .proto files or compiled .pb descriptors, making gRPC testing simple and efficient. Perfect for end-to-end testing, development environments, and CI/CD pipelines.
- Native Runtime - Single in-process engine without runtime gRPC code generation
- Descriptor Sources - Load API from
.proto, compiled.pb, BSR modules, or gRPC reflection - Dynamic
.pbService Loading - Load compiled protobuf descriptors at runtime via API without restarts - Hot Stub Management - Create, update, and remove stubs via API/UI without server restarts
- Flexible Matching -
equals,contains,matches, headers, priority, and match limits - Array-Aware Matching - Optional array-order flexibility to reduce brittle test assertions
- Dynamic Templates - Build responses from request payload, headers, and stream context
- Complete gRPC Coverage - Unary, server streaming, client streaming, and bidirectional streaming
- Error, Details, and Delay Simulation - Return realistic gRPC status codes, details (
Any), and response timing - TLS and mTLS Support - Run secure gRPC/HTTP test environments with native TLS options
- Advanced Protobuf Type Support - Handle well-known and extended protobuf types (
google.protobuf.*,google.type.*) - YAML/JSON + Schema - Author stubs in either format with JSON Schema IDE validation
- Plugin Ecosystem - Extend functions with Go plugins and matching builder image tags
- Operational APIs - Health endpoints, descriptors API, stubs API, and web dashboard
- Embedded SDK (Experimental) - Run GripMock inside Go tests/services with verification helpers
- MCP API (Experimental) - Streamable MCP endpoint for agent and tool integrations
- Upstream Modes (Experimental) -
proxy,replay,capturemodes for gradual migration from live upstream services to local mocks
Full Documentation - Complete guide with examples
- Descriptor API (
/api/descriptors): runtime loading of compiled proto descriptors (.pb) with validated curl workflow: docs - Upstream Modes (Experimental):
proxy,replay,capturewith practical rollout guidance: docs - Embedded SDK (Experimental): in-process testing with stubs, verification,
sdk.By(fullMethod)helpers, and context-aware remote checks: docs - GitHub Actions (CI/CD): official workflow action to download, start, wait for readiness, and stop GripMock automatically: docs
GripMock started as a fork of tokopedia/gripmock, and then evolved into an independent, fully rewritten project.
Today the project focuses on a native in-process architecture and practical testing workflows:
- Native runtime without runtime gRPC code generation
- Flexible descriptor sources:
.proto, compiled.pb, BSR modules, and gRPC reflection - Runtime operations: hot stub updates and descriptor loading via API
- Complete gRPC coverage: unary, server/client streaming, and bidirectional streaming
- Progressive upstream migration: reverse proxy, local-first replay, and capture-based stub bootstrap
- Extensibility and integrations: plugins, Embedded SDK, and MCP API
For architecture details and benchmark methodology, see: Performance Comparison
Access the web dashboard at http://localhost:4771/ to manage your stubs visually.
Choose your preferred installation method:
brew tap gripmock/tap
brew install --cask gripmockcurl -s https://raw.githubusercontent.com/bavix/gripmock/refs/heads/master/setup.sh | sh -sirm https://raw.githubusercontent.com/bavix/gripmock/refs/heads/master/setup.ps1 | iexdocker pull bavix/gripmockFor plugin builds, use the paired builder image:
docker pull bavix/gripmock:v3.7.1-buildergo install github.com/bavix/gripmock/v3@latestStart with a .proto file:
gripmock service.protoAdd static stubs:
gripmock --stub stubs/ service.protoLoad API directly from Buf Schema Registry (BSR):
gripmock --stub third_party/bsr/eliza buf.build/connectrpc/elizaLoad API from live gRPC server reflection:
gripmock grpc://localhost:50051
gripmock grpcs://api.company.local:443With options:
gripmock grpc://localhost:50051?timeout=10s
gripmock grpcs://10.0.0.5:8443?serverName=api.company.local
gripmock grpc://localhost:50051?bearer=<token>Use upstream modes over reflection (Experimental):
# Pure reverse proxy through GripMock
gripmock grpc+proxy://localhost:50051
# Local stubs first, then upstream fallback on matcher miss
gripmock grpc+replay://localhost:50051
# Replay + record upstream misses into GripMock stubs
gripmock grpc+capture://localhost:50051For private BSR modules:
BSR_BUF_TOKEN=<token> gripmock --stub stubs/ buf.build/acme/private-apiFor self-hosted BSR:
BSR_SELF_BASE_URL=https://bsr.company.local \
BSR_SELF_TOKEN=<token> \
gripmock --stub stubs/ bsr.company.local/team/paymentsUsing Docker:
docker run -p 4770:4770 -p 4771:4771 \
-v $(pwd)/stubs:/stubs \
-v $(pwd)/proto:/proto \
bavix/gripmock --stub=/stubs /proto/service.proto- Port 4770: gRPC server
- Port 4771: Web UI and REST API
Use the official action bavix/gripmock-action to run GripMock in CI pipelines.
name: test
on: [push, pull_request]
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Start GripMock
uses: bavix/gripmock-action@v1
with:
source: proto/service.proto
stub: stubs
- name: Run tests
run: go test ./...What the action does:
- Downloads GripMock from GitHub Releases (
latestor pinnedversion) - Starts GripMock in background and waits for readiness (
/api/health/readiness) - Exposes addresses via outputs (
grpc-addr,http-addr) for test steps - Stops GripMock automatically in the post step
More examples and full inputs/outputs: GitHub Actions guide.
Check out our comprehensive examples in the examples folder:
- Streaming - Server, client, and bidirectional streaming
- File Uploads - Test chunked file uploads
- Real-time Chat - Bidirectional communication
- Data Feeds - Continuous data streaming
- Authentication - Header-based auth testing
- Performance - High-throughput scenarios
Stub (universal):
# yaml-language-server: $schema=https://bavix.github.io/gripmock/schema/stub.json
# examples/projects/greeter/stub_say_hello.yaml
- service: helloworld.Greeter
method: SayHello
input:
matches:
name: ".+"
output:
data:
message: "Hello, {{.Request.name}}!" # dynamic template lives in outputNotes:
- Put dynamic templates only in
output(e.g.,data,headers,stream). - Keep
inputmatching static (no{{ ... }}inequals/contains/matches).
# Start server
go run main.go examples/projects/greeter/service.proto --stub examples/projects/greeter
# Call via grpcurl
grpcurl -plaintext -d '{"name":"Alex"}' localhost:4770 helloworld.Greeter/SayHelloExpected response:
{
"message": "Hello, Alex!"
}service: Greeter
method: SayHello
input:
equals:
name: "gripmock"
output:
data:
message: "Hello GripMock!"Priority System:
- service: UserService
method: GetUser
priority: 100 # Higher priority
input:
equals:
id: "admin"
output:
data:
role: "administrator"
- service: UserService
method: GetUser
priority: 1 # Lower priority (fallback)
input:
contains:
id: "user"
output:
data:
role: "user"Streaming Support:
service: TrackService
method: StreamData
input:
equals:
sensor_id: "GPS001"
output:
stream:
- position: {"lat": 40.7128, "lng": -74.0060}
timestamp: "2024-01-01T12:00:00Z"
- position: {"lat": 40.7130, "lng": -74.0062}
timestamp: "2024-01-01T12:00:05Z"GripMock supports dynamic templates in the output section using Go's text/template syntax.
- Access request fields:
{{.Request.field}} - Access headers:
{{.Headers.header_name}} - Client streaming context:
{{.Requests}}(slice of received messages),{{len .Requests}},{{(index .Requests 0).field}} - Bidirectional streaming:
{{.MessageIndex}}gives the current message index (0-based) - Math helpers:
sum,avg,mul,min,max,add,sub,div - Utility:
json,split,join,upper,lower,title,sprintf,int,int64,float,round,floor,ceil
Important rules:
- Do not use dynamic templates inside
input.equals,input.contains, orinput.matches(matching must be static) - For server streaming, if both
output.streamandoutput.error/output.codeare set, messages are sent first and then the error is returned. Ifoutput.streamis empty, the error is returned immediately
Header Matching:
service: AuthService
method: ValidateToken
headers:
equals:
authorization: "Bearer valid-token"
input:
equals:
token: "abc123"
output:
data:
valid: true
user_id: "user123"GripMock supports three powerful matching strategies:
input:
equals:
name: "gripmock"
age: 25
active: trueinput:
contains:
name: "grip" # Matches "gripmock", "gripster", etc.input:
matches:
email: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
phone: "^\\+?[1-9]\\d{1,14}$"GET /api/stubs- List all stubsPOST /api/descriptors- Load protobuf descriptor set (FileDescriptorSet) at runtimePOST /api/stubs- Add new stubPOST /api/stubs/search- Find matching stubDELETE /api/stubs- Clear all stubsGET /api/health/liveness- Health checkGET /api/health/readiness- Readiness check
# Add a stub
curl -X POST http://localhost:4771/api/stubs \
-H "Content-Type: application/json" \
-d '{
"service": "Greeter",
"method": "SayHello",
"input": {"equals": {"name": "world"}},
"output": {"data": {"message": "Hello World!"}}
}'
# Search for matching stub
curl -X POST http://localhost:4771/api/stubs/search \
-H "Content-Type: application/json" \
-d '{
"service": "Greeter",
"method": "SayHello",
"data": {"name": "world"}
}'Add schema validation to your stub files for IDE support:
JSON files:
{
"$schema": "https://bavix.github.io/gripmock/schema/stub.json",
"service": "MyService",
"method": "MyMethod"
}YAML files:
# yaml-language-server: $schema=https://bavix.github.io/gripmock/schema/stub.json
service: MyService
method: MyMethodGripMock supports simplified integration with Buf Schema Registry:
# Public BSR (default)
BSR_BUF_BASE_URL=https://buf.build
BSR_BUF_TOKEN=<token>
# Self-hosted BSR
BSR_SELF_BASE_URL=https://bsr.company.local
BSR_SELF_TOKEN=<token># Public module
gripmock buf.build/connectrpc/eliza
# Self-hosted module
gripmock bsr.company.local/team/payments:main
# With stubs
gripmock --stub stubs/ bsr.company.local/team/paymentsGripMock automatically routes modules:
buf.build/owner/repo→ uses Buf profilebsr.company.local/owner/repo→ uses Self profile
For details see BSR Documentation.
GripMock supports descriptor loading from gRPC reflection using endpoint schemes:
grpc://host:port(insecure)grpcs://host:port(TLS)
Supported query parameters:
timeout(default5s)bearer(Authorization token)serverName(TLS SNI override)
Examples:
gripmock grpc://localhost:50051
gripmock grpcs://api.company.local:443
gripmock grpcs://10.0.0.5:8443?serverName=api.company.localFull guide: gRPC Reflection Source.
Upstream modes work on top of reflection sources and define runtime behavior:
proxy- pure reverse proxyreplay- local-first + upstream fallbackcapture- replay + automatic stub recording from upstream
Mode guides:
- 📖 Documentation - Complete guides and examples
- 🧪 Testing gRPC with Testcontainers - Article by @AndrewIISM
- 📋 JSON Schema - Stub validation schema
- 🔗 OpenAPI - REST API documentation
We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by the GripMock community


