Disclosure: I work on Mockzilla, which competes with Mockoon. Everything below
was run on one laptop, and there is a link to the longer comparison at the end.
Mockoon is a quick way to get a Stripe mock running. Import Stripe's OpenAPI
spec into the desktop app, fix the responses your tests care about, and every
route answers on localhost:3000.
Then Stripe ships a new API version, and you import the new spec over the old
one.
What basil moved
In March 2025 Stripe released an API version called basil. It moved
current_period_start and current_period_end from the subscription to each
subscription item. If your code handles subscriptions, it probably reads one of
them.
The reimport
When you import a spec, Mockoon converts it into its own file format, and from
then on that file is what you edit and run. Stripe's spec is 6.4 MB. The Mockoon
file it turns into is 30.5 MB. Mockoon's own documentation calls import "a good
starting point but not a way to share your mock APIs".
Reimport only adds. From the same docs: "No existing routes or responses will be
modified or deleted".
I imported the Stripe spec from before basil, then reimported the basil one.
Mockoon added 2 new routes. The other 559 stayed as they were, this one
included:
$ curl -s localhost:3000/v1/subscriptions/sub_123 \
| jq '{current_period_end, item_period_end: .items.data[0].current_period_end}'
{
"current_period_end": 13345,
"item_period_end": null
}
Code already updated for basil reads the item and gets null. Older code
reads the top-level field, and its tests pass against a field Stripe no longer
sends. Two endpoints that basil removed still answer 200.
To get a changed route from the new spec, you delete the route and import
again. That also deletes whatever you had edited in it.
The empty strings
You will have edited some routes, because Mockoon fills Stripe's text fields
with empty strings. Create a customer the way a test would:
$ curl -s localhost:3000/v1/customers -d email=jenny@example.com -d "name=Jenny Rosen" \
| jq -c '{id, object, email, name, currency}'
{"id":"","object":"customer","email":"","name":"","currency":""}
Across the whole Stripe mock, 223,537 fields are empty, and currency alone is
empty in 4,641 places. The empty id breaks the next step of the test: fetching
that customer requests /v1/customers/, and that route answers with the
customer list.
The fix is per route: open the route and edit its response body, for example
with a template helper that copies the email from the request. A route you fixed
stays on the old spec after every reimport.
Start-up and memory
Mockoon handles the full Stripe spec. Prism, for one, did not open a port on it
in 30 minutes. I ran both tools on Stripe's current spec, three runs each, timed
from launch to first response:
| Stripe, 6.4 MB | Mockoon CLI 9.8.0 | Mockzilla 2.8.16 |
|---|---|---|
| First response, from the spec | 1,335 to 1,386 ms | 210 to 242 ms |
| Memory, warm | 477 to 487 MiB | 194 MiB |
| First response, from the converted file | 457 to 488 ms at 280 MiB | no such file |
| What you install | Node.js and 252 npm packages, 103 MB | one 40 MiB binary |
The CLI converts the spec again on every start, which is where the extra second
goes. On a laptop none of this matters much. CI pays it in every job, and
Mockoon's GitHub Action spent 8 to 10 seconds on the npm install alone.
When Mockoon is the better choice
If your API has no OpenAPI spec, use Mockoon. You build the routes by hand in
its desktop app and set each response by clicking.
A Mockoon route can also hold several responses and pick one by rule, such as a
402 when the request contains pm_card_visa_chargeDeclined, Stripe's test
payment method for a declined card. Callbacks send a follow-up request after a
call, which is how you fake a webhook. A record you create with POST comes back
on GET. Mockzilla needs Go code to pick a response by request, keeps no data
between calls, and does not read the Swagger 2.0 files Mockoon accepts.
If your mock starts from a spec
The other approach is a mock server that reads the spec on every start.
Replacing the file is the update. Given the basil spec, Mockzilla puts the
period fields on the item and answers 404 on the two removed endpoints.
The fixes go in a separate file next to the spec, keyed by field name:
currency: ["usd", "eur", "gbp"]
in-response:
email: "request:email"
name: "request:name"
One currency line covers every currency field in Stripe's responses. When
Stripe ships the next version you replace the spec and keep this file.
The full comparison has both tools side by side, latency and error settings,
replay, what CI looks like on each side, and the prices:
Mockoon alternative: keep your mock API in sync with your OpenAPI spec
Top comments (0)