// service virtualization for HTTP and S3

your dependencies,
in disguise

Imposters spins up fake HTTP APIs and S3 buckets that your code talks to like the real thing. Script them over a REST API or a JSON file, swap their answers live, and make them fail exactly when your tests need them to.

npx imposters start
read the docs →
~/my-app
$ npx imposters start --config imposters.json
Created HTTP imposter "users-api" on port 3000
Created S3 imposter "assets" on port 7070
Imposters admin server running on http://127.0.0.1:2525 (bound to 127.0.0.1, runtime: node)
Admin UI: http://127.0.0.1:2525/_ui
# in a second terminal
$ curl localhost:3000/users/42
{"id":"42","name":"Alice"}
$ cat imposters.json
{
  "imposters": [
    {
      "name": "users-api",
      "port": 3000,
      "stubs": [
        {
          "predicates": [
            { "field": "method", "operator": "equals", "value": "GET" },
            { "field": "path", "operator": "matches", "value": "^/users/\\d+$" }
          ],
          "responses": [
            {
              "body": {
                "id": "${$substringAfter(request.path, '/users/')}",
                "name": "Alice"
              }
            }
          ]
        }
      ]
    },
    { "name": "assets", "port": 7070, "protocol": "S3" }
  ]
}
Inspired by Mountebank, rebuilt for TypeScript and Effect · MIT · Node or Bun

how a request is fooled

  1. 01 adminOne server on 2525 creates imposters over REST, or loads them from a JSON file.
  2. 02 portEach imposter answers on its own port with an ordered list of stubs.
  3. 03 matchThe first stub whose predicates fit method, path, headers, query and body replies, calling other services first if it has callbacks.
  4. 04 fallbackOtherwise an extension like S3 answers, a proxy forwards, or it is a 404.

imposters --help

--hot-reload
Change a stub mid-run; the next request gets the new answer.
--predicates
equals, contains, startsWith, matches, exists.
--templates
{{request.path}} substitution and ${JSONata} expressions.
--cycle
Several responses per stub: sequential, random or repeat.
--proxy
Forward to the real service, or record its answers as stubs.
--callbacks
Call other services before answering, or fire webhooks after; loops end in a 508.
--inspect
Request log, error rate and latency percentiles per imposter.
--ui
/_ui for every imposter, /_admin inside each one.
--test
Typed TypeScript client and withImposter for your test suite.
These read as flags for flavour; they are features, not CLI options.
// try it: no install, nothing leaves your browser

fool a request

Edit the stubs, send a request, read the answer. This is the matcher, templating and response cycling from Imposters' own source, bundled into the page. Send POST /charges twice: the second one is declined.

playground · runs the real matcher in your browser

loading the matcher…

request
response
press send
// "protocol": "S3"

an S3 bucket
that fails on cue

An in-memory S3 for the AWS SDK: buckets, objects, copies, batch deletes and listings, with nothing to install. Stubs go first, so one key can throttle or time out while the rest of the bucket behaves.

the S3 emulator →
stub · throttle one key
{
  "predicates": [
    { "field": "path", "operator": "equals", "value": "/photos/hero.jpg" }
  ],
  "responses": [{
    "status": 503,
    "headers": { "content-type": "application/xml" },
    "body": "<Error><Code>SlowDown</Code></Error>"
  }]
}

put on the mask

npx imposters start
get started →