Mockers is a CLI + HTTP server that lets you spin up fake APIs from files in seconds.
If you need a quick backend for frontend work, contract testing, demos, QA, or local integration tests — this thing is exactly for that. No heavy setup, no DB, no headache.
You have requests coming in. You want deterministic responses. You want them fast.
Mockers maps URL + HTTP method to files, returns file contents as responses, and gives you extra controls like:
- custom status codes,
- response delay,
- custom headers,
- admin API,
- request forwarding to a real origin,
- optional disk write-through caching.
So it can work as both:
- a pure mock server, and
- a "mock-first, proxy-if-missing" server.
Build from source:
cargo build --releaseBinary will be in target/release/mockers.
Run server with defaults:
mockers serveDefaults:
- host:
0.0.0.0 - port:
8080 - https port:
8443 - mocks dir:
./mocks
If ./mocks does not exist, Mockers creates it.
mockers <COMMAND>Available commands:
serve— run HTTP serverconfig— show effective global Mockers configurationinit— initialize global Mockers configuration filecompletion— generate shell completion script
Aliases exist for serve, config, and init; check --help.
Mockers supports a hierarchical global configuration system via .mockers files.
When any command runs, Mockers walks from the current working directory up to the filesystem root,
reads every .mockers file it finds, and merges them. Config fields from closer directories override
those from parent directories.
You can create a user-level global config in your home directory:
mockers init # non-interactive, writes defaults
mockers init -i # interactive setup with promptsThe file is written to $HOME/.mockers in JSON format.
CLI flags always take precedence over global config values, which in turn override built-in defaults.
Supported .mockers fields (all optional, camelCase keys):
| Field | Type | Description |
|---|---|---|
host |
string | Interface to bind |
port |
number | HTTP port |
httpsPort |
number | HTTPS port |
mocks |
string | Path to mocks directory |
cors |
boolean | Enable CORS headers |
preflight |
"mirror" | "permissive" |
Preflight handling |
delayMs |
number | Global response delay (ms) |
origin |
string | Fallback upstream URL |
adminBaseUrl |
string | Admin API base path |
logRequest |
"info" | "debug" | "trace" |
Request logging level |
verbosity |
"info" | "debug" | "trace" |
Process verbosity level |
proxyBodyMaxBytes |
number | Max upstream response body (bytes) |
proxy |
string | Proxy connection string for upstream requests (socks5, http, https) |
mockers serve [OPTIONS]| Flag | Default | Description |
|---|---|---|
--host |
0.0.0.0 |
Interface to bind to |
--port, -p |
8080 |
Port to listen on |
--https-port |
8443 |
HTTPS port to listen on |
--mocks, -m |
mocks |
Directory with mock files |
--cors, -c |
false |
Adds CORS headers (Access-Control-Allow-Origin: *). Can be passed as --cors (true) or --cors=false |
--preflight |
unset | Auto-handle browser OPTIONS preflight requests |
--delay-ms, -d |
0 |
Global response delay in ms |
--origin, -o |
unset | Fallback upstream server when mock is missing |
--admin-base-url, -a |
unset | Enables admin API + Swagger under given absolute base path |
--log-request, -l |
info |
Request logging level: info, debug, trace |
--verbosity, -v |
info |
Process/service verbosity level: info, debug, trace. With debug/trace, startup parameters are printed |
--proxy-body-max-bytes |
16777216 (16 MiB) |
Maximum upstream response body size when proxying. Hard capped at 32 MiB |
--proxy |
unset | Proxy connection string for upstream requests. Supports socks5, http, https — e.g. socks5h://127.0.0.1:1080 |
Mockers handles Ctrl+C (SIGINT) for a clean server shutdown. When interrupted, it stops accepting new connections and lets in-flight requests complete.
mockers serve can run with HTTPS enabled.
To turn it on, put a TLS certificate and private key into your mocks directory and name them cert.pem and key.pem. No magic, just files.
Mockers uses a separate port for HTTPS, so HTTP and HTTPS do not have to fight over the same one. Configure it with the httpsPort field in the global config file or with the --https-port flag.
If cert.pem, key.pem, and an HTTPS port are present, Mockers will start serving HTTPS.
For local development, you can generate certificates with any tool you prefer. Mockers does not care. If you want the easy route, use mkcert. It can create a local root CA, add it to your system trust store, and issue a certificate for 127.0.0.1 or a local domain.
If --preflight is enabled, Mockers can answer browser preflight requests automatically:
mirror— mirrors requested origin/method/headers back to the browser.permissive— basically "allow everything" mode (*, all methods, etc.).
Good for local dev when CORS fights you.
info: method + path/query.debug: method + path/query + headers.trace: method + path/query + headers + body.
Controls process/service output (separate from request logging):
info: normal startup/shutdown messages.debug: startup parameters and additional diagnostics.trace: detailed internal tracing.
Mock file naming convention is:
<route_path>.<http_method_lowercase>
Examples:
user.get -> GET /user
login.post -> POST /login
config.put -> PUT /config
Nested routes are just nested folders/files:
mocks/
├─ users/
│ ├─ list.get
│ └─ create.post
└─ auth/
└─ login.post
This gives you:
GET /users/listPOST /users/createPOST /auth/login
When your project already has a populated mocks/ directory, you can read it as a contract map.
Example:
mocks/
├─ auth/
│ ├─ login.post
│ ├─ refresh.post
│ └─ config.json
├─ users/
│ ├─ me.get
│ ├─ me.patch
│ └─ config.json
└─ health.get
How to interpret this:
auth/login.postmeansPOST /auth/loginauth/refresh.postmeansPOST /auth/refreshusers/me.getmeansGET /users/meusers/me.patchmeansPATCH /users/mehealth.getmeansGET /health
Important details:
- File extension is always the HTTP method (
.get,.post,.patch, ...). - Path segments come from folders + filename stem.
config.jsonis local to its folder and config keys must match mock filenames in that same folder.- Body is returned exactly from file content, while
Content-Typeis auto-detected from bytes (JSON/CSS/text/binary, etc.).
A mock file can be treated as a prompt for an OpenAI-compatible LLM provider instead of being returned as static bytes.
To enable this, the file must be UTF-8 text and start with YAML frontmatter delimited by exact --- lines.
Example mocks/users/profile.get:
---
$mockers:
prompt: true
api_endpoint: https://api.openai.com/v1/chat/completions
env_key: OPENAI_API_KEY
model: gpt-4o-mini
proxy: socks5h://127.0.0.1:1080
ttl: 60000
---
Return a realistic JSON user profile for the current request.
Use the request path and headers when useful.Frontmatter format:
- Frontmatter must be at the very beginning of the mock file.
- Opening and closing delimiters must be lines containing exactly
---. - The Mockers-specific config lives under the literal
$mockersYAML key. $mockers.prompt: trueis required to call the LLM. If it is missing orfalse, the file is served as a normal static mock.- Invalid or unparsable frontmatter is ignored and the file is served as a normal static mock.
Supported $mockers fields:
| Field | Type | Required | What it does |
|---|---|---|---|
prompt |
boolean | yes | Enables LLM generation when true |
api_endpoint |
string | yes | OpenAI-compatible chat completions endpoint |
model |
string | yes | Model name sent in the provider request |
env_key |
string | no | Environment variable containing a bearer token for Authorization |
proxy |
string | no | Proxy URL used only for this LLM provider request |
ttl |
number | no | In-memory generated-response cache TTL in milliseconds; default is 0 |
When a prompt mock is handled, Mockers sends the mock file content as the user prompt and appends request context to the system prompt: method, URI, headers, and body. The provider request uses stream: false and temperature: 0 for deterministic responses.
The provider response must look like an OpenAI chat completion response. Mockers uses the first choice only, requires finish_reason: "stop", requires assistant role, and returns message.content as the HTTP response body. Content-Type is inferred from the generated body. Per-mock statusCode and headers from config.json are still applied.
If the LLM request fails, the provider returns a non-success status, required frontmatter fields are missing, or the response shape is unsupported, Mockers returns 502 Bad Gateway for that request.
In any mock directory, you can add a config.json file.
Keys are mock file names in the same directory (like user.get).
Example:
{
"user.get": {
"delayMs": 1200,
"statusCode": 201,
"headers": {
"X-Server": "Mockers"
},
"cacheMode": "overwrite",
"disabled": false
}
}| Field | Type | What it does |
|---|---|---|
delayMs |
number | Per-mock delay in ms |
statusCode |
number | Per-mock HTTP status |
headers |
object string->string | Extra response headers |
cacheMode |
overwrite | nocache |
Controls write-through behavior when proxying to origin |
disabled |
boolean | If true, mock returns 404 immediately |
For a matching mock file:
- status defaults to
200 - delay defaults to global
--delay-msvalue (or0) - headers default to empty
- cache mode defaults to
nocache - disabled defaults to
false
If a config key is missing, defaults are used.
For every incoming request, Mockers roughly does this:
- Build mock filename from request path + method.
- Read adjacent
config.json. - If the mock is disabled, return
404immediately. - Handle preflight requests when
--preflightis enabled. - If the mock file exists and has
$mockers.prompt: truefrontmatter, try to generate the response through the configured LLM provider. - Otherwise, try the static file-based mock.
- If file mock is missing:
- if
--originis set -> proxy request to origin, - else -> return
404.
- if
- If proxied and
cacheMode=overwrite, write response to disk asynchronously (mock file + config.json).
So you can warm up mocks from a real backend automatically.
mockers configShows the effective global Mockers configuration resolved for the current directory.
Values are pulled from .mockers files (from CWD up to root) and merged.
Aliases: configuration, settings, preferences, prefs.
Takes no parameters. It prints a human-readable report with all supported fields: host, port, HTTPS port, mocks path, CORS, preflight, delay, origin, admin base URL, request log level, verbosity level, proxy body max bytes, proxy.
If a value is not set in any .mockers file, it shows as [unset] (except proxy,
which displays as Proxy IS set or Proxy is NOT set).
mockers init [OPTIONS]Initializes the global Mockers configuration file at $HOME/.mockers.
Alias: setup.
| Flag | Default | Description |
|---|---|---|
--interactive, -i |
false |
Interactive mode with prompts for each config field |
Without --interactive, writes built-in defaults to ~/.mockers.
If ~/.mockers already exists, you will be asked for confirmation before overwriting.
Enable admin surface with:
mockers serve --admin-base-url /__adminThen you'll get:
- REST API under
/__admin/api/v2/... - Swagger UI under
/__admin/swagger
The admin API works directly with file-based mocks on disk.
Creating a mock creates the mock file and updates config.json.
Deleting a mock removes the mock file and cleans up its config entry.
Listing mocks returns only route path + HTTP method pairs.
POST /api/v2/mocks— get all mocks (path+methodonly)POST /api/v2/mocks/create— create a new file-based mockPOST /api/v2/mocks/config— get mock config by path+methodPOST /api/v2/mocks/delete— delete a file-based mock by path+method
Swagger also documents request/response schemas and known admin error codes.
Two separate things exist:
--corsadds regularAccess-Control-Allow-Origin: *to regular responses.--preflighthandles OPTIONS preflight negotiation automatically.
Use both if you want easiest browser interop in local env.
mockers serve --mocks ./mocksmockers serve --mocks ./mocks --origin https://example-api.devOptional: set cacheMode: "overwrite" for selected mocks to save upstream responses to disk.
mockers serve --cors --preflight permissivemockers serve --admin-base-url /__adminOpen: http://localhost:8080/__admin/swagger
- Admin base URL must be an absolute path (like
/__admin). - Mockers only treats files with valid HTTP method extensions as mocks.
- If a path in
--mockspoints to a file/symlink instead of dir, command fails. - Relative
--mockspaths are resolved from current working directory. - Response body mime is auto-detected from content.
JSON schema for per-directory config.json:
docker build -t mockers-dockers .This builds a production image for mockers.
The mocks directory must be mounted from the host into /app/mocks inside the container.
docker run --rm \
-p 8080:8080 \ # if mockers serves HTTP
-p 8443:8443 \ # if mockers serves HTTPS
-v "/path/to/host/mocks/directory:/app/mocks" \
mockers-dockers serveThis will:
- expose the server on port
8080(or8443when HTTPS enabled, see HTTPS support) - mount the local
/path/to/host/mocks/directorydirectory into the container as/app/mocks - start
mockers serve
The application always listens on port 8080 or 8443 inside the container.
To expose it on a different host port, change the Docker port mapping:
docker run --rm \
-p 9090:8080 \
-v "/path/to/host/mocks/directory:/app/mocks" \
mockers-dockers serveIn this example:
- host port:
9090 - container port:
8080
The container always expects mocks at:
/app/mocksA local directory must be mounted there when the container is started.
Read-only mount is recommended if mockers only needs to read mock files:
-v "/path/to/host/mocks/directory:/app/mocks:ro"If write access is required, remove :ro:
-v "/path/to/host/mocks/directory:/app/mocks"docker build -t mockers-dockers .
docker run --rm \
-p 8080:8080 \
-v "/path/to/host/mocks/directory:/app/mocks:ro"
mockers-dockers serve \
--cors \
--delay-ms 150 \
--log-request debugmockers can generate shell completion scripts for supported shells.
To enable completions, add the following line to your shell startup file:
source <(mockers completion -s SHELL)Replace SHELL with one of the supported shells:
bashzshfishelvishpowershell
Add this line to ~/.bashrc:
source <(mockers completion -s bash)Add this line to ~/.zshrc:
source <(mockers completion -s zsh)Add this line to your Fish config file, usually ~/.config/fish/config.fish:
source (mockers completion -s fish | psub)Add this line to your Elvish config file, usually ~/.config/elvish/rc.elv:
eval (mockers completion -s elvish | slurp)Add the generated script to your PowerShell profile:
mockers completion -s powershell | Out-String | Invoke-ExpressionYou can place this command in your PowerShell profile file so that completions are loaded automatically in every session.
Huge thanks to @Caik, whose Go version sparked the original idea. Also thanks to bloodvez and silentroach.
MIT License.