mockttp: HTTP mocking that tests the real request, not a stubbed function
Powerful friendly HTTP mock server & proxy library
At a glance
- What is it?
- mockttp is a Node and browser library that runs a mock HTTP server or a mocking proxy, so integration tests exercise the actual requests your code sends instead of a stubbed HTTP function. It suits teams that want one test suite to work against real traffic in Node and in the browser.
- Who is it for?
- mockttp is a good fit for a team that has outgrown stubbing the HTTP function in process, that wants its integration tests to exercise the real requests their client library would send, and that runs the same suite in Node and in the browser. It is the wrong tool for unit testing pure functions that never touch the network, and it is the wrong tool if you need WebSocket or other non-HTTP protocols mocked, since the scope here is HTTP requests and responses.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why stubbing the HTTP function gives you a false result
The argument for the library is made in the readme and it is worth restating because it is the reason to switch. HTTP testing is the most common and well supported use case, and there are many tools for it, but they typically work by stubbing the HTTP functions in process at the JavaScript level. The readme lists what that costs you. It ties you to a specific environment, it does not truly test the real requests your code would send, and it only works for requests made in the same JavaScript process. The summary is that it is inflexible, limiting and inaccurate, and often unreliable and tricky to debug as well. Each of those is a specific failure. A stub cannot tell you that your client sends a malformed header, because the stub replaced the layer that would have sent it. A stub does not exercise redirects, because the redirect handling lives in the real HTTP stack. And a stub cannot observe a request made by a native module or a subprocess, because that request never passes through the stubbed function at all. Mockttp's answer is to be the server rather than to replace the function.
The four steps of every mockttp test
The getting started section reduces the whole library to four steps, and knowing them tells you the shape of the API before you read any reference. You start a Mockttp server, you mock the endpoints you are interested in, you make some real HTTP requests, and you assert on the results. The minimal example uses plain promises with Mocha, Chai and Superagent, and it works out of the box in Node and in modern browsers:
const superagent = require("superagent");
const mockServer = require("mockttp").getLocal();
describe("Mockttp", () => {
// Start your mock server
beforeEach(() => mockServer.start(8080));
afterEach(() => mockServer.stop());
it("lets you mock requests, and assert on the results", async () => {
// Mock your endpoints
await mockServer.forGet("/mocked-path").thenReply(200, "A mocked response");
// Make a request
const response = await superagent.get("http://localhost:8080/mocked-path");
// Assert on the results
expect(response.text).to.equal("A mocked response");
});
});The important detail is that the server is started and stopped in the test hooks, and the endpoint is registered with an await before the request is made. The mocking call returns a promise that resolves to a mock object, and that object is what you later query for the requests it received. The example above uses the forGet method with a path, which is the shorthand for a path matcher.
Dynamic ports are what make parallel tests possible
The second example in the documentation is the one that changes how a test suite is written, and the reason is the port. The comment in the code explains it: there is no start port here, so a free one is found dynamically instead. The server is started with no argument, and the mock URL is obtained from the server rather than being hard-coded:
// Try mockServer.url or .urlFor(path) to get the dynamic URL for the server's port
let response = await superagent.get(mockServer.urlFor("/mocked-endpoint"));That one change is what allows the same suite to run in parallel without port collisions, and the feature list describes the same idea as safe parallel mocking with autoconfiguration of ports, mock URLs and proxy settings. The reason this matters is that a fixed port in a test file is a serialisation point: two test files that both bind 8080 cannot run at the same time, so the suite gets slower as it grows. With a dynamic port, the tests are independent, and the feature list claims fast and safe parallel testing as a result. The same example also shows the request verification half of the API. The mock object is captured, the request is made, and the mock is then queried for what it saw:
const endpointMock = await mockServer.forGet("/mocked-endpoint").thenReply(200, "hmm?");
await superagent.get(mockServer.urlFor("/mocked-endpoint"));
// Inspect the mock to get the requests it received and assert on their details
const requests = await endpointMock.getSeenRequests();
expect(requests.length).to.equal(1);So a mock is not just a response generator, it is also a record of the traffic it received, which is what turns it into an assertion target.
Proxying lets you intercept traffic your code sends elsewhere
The third example in the documentation covers the other mode, which is proxying rather than mocking a server you call directly. The mock is registered against a full URL rather than a path, and the request is then routed through the proxy:
// Match a full URL instead of just a path to mock proxied requests
await mockServer.forGet("http://google.com").thenReply(200, "I can't believe it's not google!");
// One of the many ways to use a proxy - this assumes Node & superagent-proxy.
// In a browser, you can simply use the browser settings instead.
let response = await superagent.get("http://google.com").proxy(mockServer.url);The distinction between the two modes is the difference between a mock server and a mocking proxy, and the feature list names both. The mock server is what you call directly, and the proxy is what transparently intercepts requests sent elsewhere. The second is the interesting one, because the feature list says mock requests inside or outside your process or tab, including subprocesses, native code and remote devices, and that is precisely the class of request a stub cannot see. In a browser the proxy is configured through the browser settings, while in Node it needs a proxy agent, and the example uses superagent-proxy to do it. The library is also described as battle-tested as a scriptable rewriting proxy, powering all the HTTP internals of HTTP Toolkit, with the claim that anything you can do with HTTP Toolkit you can automate with Mockttp as a headless script.
HTTPS interception and the one dependency you have to add
Mocking HTTPS is where a lot of these tools stop, and Mockttp handles it with built-in self-signed certificate generation. The feature list has intercepting HTTPS as its own item. The catch is inherent to the approach rather than to this library: the client has to trust the certificate the proxy generates, which is why the browser case can rely on browser settings while the Node case needs an explicit proxy agent. Transparent proxying and HTTPS support are listed as part of what makes the tests accurate rather than in-process approximations, and the setup guide in the docs directory is the document to read for the environment-specific details of that configuration. There is also a pluggable admin API shipped as separate export paths, with a pluggable-admin entry and a mockttp-pluggable-admin entry in the package exports, which is the mechanism for a host application to control the mock server rather than only the test file.
Debuggability is treated as a first-class feature
The feature list has an entry on debugging tests, and it is unusually specific for a testing library. It promises full explainability of all mock matches and misses, mock autosuggestions, and an extra detailed debug mode. This addresses the real failure mode of HTTP mocking, which is not that the test fails but that you cannot tell whether the request never arrived, arrived with a different method, or arrived with a different path. A mock that can explain why it did not match turns a debugging session into a single run. The rest of the quality story follows the same pattern. The write modern test code entry promises promises all the way down, async and await, and strong typing with TypeScript throughout, and the documentation says the examples use Mocha, Chai and Superagent but that none of them are required, since Mockttp works with any testing tools that can handle promises, and with minor tweaks many that cannot, and it can mock requests from any library, tool or device. The package metadata backs the typing claim, with a types entry pointing at a declaration file and a custom-typings directory in the repository, and the exports map separates node and browser builds so the same import resolves to the right implementation in each environment.
Editorial conclusion
mockttp is a good fit for a team that has outgrown stubbing the HTTP function in process, that wants its integration tests to exercise the real requests their client library would send, and that runs the same suite in Node and in the browser. It is the wrong tool for unit testing pure functions that never touch the network, and it is the wrong tool if you need WebSocket or other non-HTTP protocols mocked, since the scope here is HTTP requests and responses. It is also the wrong tool if you need a general-purpose debugging proxy for arbitrary traffic, because although it can proxy and rewrite, it is built for tests rather than for interactive traffic inspection. Before adopting it, read the setup guide for the transparent proxying configuration, since that is where the environment-specific details live, and check whether your test runner supports promises, since the whole API is promise based and the documentation says many tools that cannot handle them work only with minor tweaks. The project is Apache-2.0 licensed, the last push was on 2026-10-16, and the current package version is 4.6.4.
Frequently asked questions
What is Mockttp and what does it let you test?
It is a Node and browser library that intercepts, transforms or tests HTTP requests and responses in JavaScript. It can stub server responses, verify the requests a client actually sent, intercept HTTPS with built-in self-signed certificate generation, and mock requests made inside or outside your process including subprocesses, native code and remote devices.
How do I install Mockttp and run a first test?
Install it with npm install --save-dev mockttp, then start a mock server in the test hooks, register an endpoint with forGet and thenReply, make a real request and assert on the result. The documented minimal example uses Mocha, Chai and Superagent, but none of them are required if your test runner can handle promises.
How does Mockttp support parallel test runs?
By starting the server without a fixed port so a free one is found dynamically, then reading the URL from mockServer.url or mockServer.urlFor(path) rather than hard-coding it. The feature list describes this as autoconfiguration of ports, mock URLs and proxy settings for safe parallel mocking.
How do I assert on the requests a mock received in Mockttp?
Keep the object returned by the mocking call, then call getSeenRequests on it to get the requests it received, each with details including the URL. The documented example checks the number of requests seen and the full request URL including the server's port.
Can Mockttp mock HTTPS and proxy other hosts?
Yes. It intercepts HTTPS with built-in self-signed certificate generation, and it can act as a transparent mocking proxy for requests sent to other hosts by matching a full URL instead of a path. In Node the request needs a proxy agent such as superagent-proxy, while in a browser you configure the proxy through the browser settings.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/httptoolkit-mockttp)Was this useful?