npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mocwai

v1.2.7

Published

mocwai is a quick mocking server for HTTP and Socket.IO. For dev, test, and prototyping

Downloads

196

Readme

mocwai

mocwai is a quick mocking server for HTTP, WebSocket, and Socket.IO. For dev, test, and prototyping.

Rules

  • Don't expose to bright light
  • Don't get it wet
  • Never feed after midnight

Summary

It operates off of a config file, supports serving static assets, inline data, supports automatic simple indexing of json/yaml data, as well as custom javascript handlers for more advanced use cases. Support for HTTP, raw WebSocket, and Socket.IO. Watches routes for changes and reloads on change (using --watch switch).

JSON Schema


Considerations

  • When using custom handlers in mocwai within an ESM project (i.e. {type: "module"}) you must use .cjs extension.
  • Indexed endpoints do not need to define method/methods. They automatically receive GET, POST, PATCH, PUT, and DELETE.
  • Can serve headers via "headers" key.

Links


CLI Usage

Validate Config

mocwai validate <path-to-config>

Start Mock Server

mocwai serve -c <path-to-config> [-a HOST:PORT] # Default: localhost:8080

Start Mock Server and Watch for Changes

mocwai serve -c <path-to-config> [-a HOST:PORT] --watch

After starting the server, mocwai drops you into an interactive shell where you can manually control socket behavior:

  • send <eventName> <payload> — manually emit a socket.io message to all clients.
  • quit — exit the server.

Example:

> send "hello" {"user":"foobar"}
> quit

Quick Run Down for HTTP

HTTP mocking supports three modes:

1. handler

Load a JavaScript file and call exported functions (get, post, etc.).

  • Can share one file across multiple routes.
  • Handler is loaded once and cached.
  • If using within an ESM project, you must name your extension .cjs, not .js.

2. static

Serve a static file from disk.

  • Content-Type is based on contentType field.

3. inline

Respond directly with the raw value provided in the config.

  • Accepts JSON-compatible types: object, array, number, string, boolean.

Indexing static/inline data

For "static" and "inline" types you can add the index: true key to static or inline entries when using matchType: "params" to automatically index array data by path param.

Example:

{
  "matchType": "params",
  "path": "/things/:id",
  "index": true,
  "inline": [
    {"id": 1, "name": "thing-one"},
    {"id": 2, "name": "thing-two"}
  ]
}
  • This builds an index by id. Requests to /things return the full array, while /things/:id returns a single item matched to th key "id".
  • The following endpoints will be provided automatically:
    • GET /things
    • POST /things
    • PUT /things/:id
    • PATCH patch /things/:id
    • DELETE /things/:id
  • The updated inline/static data (from POST/PUT/PATCH/DELETE) will NOT persist across restarts.

Serving headers

You can serve custom headers via "headers" key.

{
  "method": "GET",
  "matchType": "string",
  "path": "/",
  "inline": "ok",
  "headers": {
    "X-foo": "foobar"
  }
}

Serving folders

{
  "method": "GET",
  "matchType": "string",
  "path": "/",
  "static": "folder-path"
}

see examples/folders

Adding files not found by file watcher

When executed in watch mode via --watch, all files referenced in "static" or "handler" routes will be monitored for changes and upon change, cause the server to reload all routes. This works nicely most of the time, but this may miss some files when using "handler" type routes. While the handler itself is tracked for changes, assets it uses will not be tracked (for example data that it relies on). To track assets used by the handler for changes, use the "assets" key and provide an array of the additional paths you would like to monitor for changes. Technically, the assets don't have to be related to your handler.

{
  "method": "GET",
  "matchType": "params",
  "path": "/widgets/:name",
  "handler": "./my-handler/main.js", // in this case ./main.js relies on ./data.json
  "assets": [
    "./my-handler/data.json",
    "../some/possibly/related/file.txt"
  ]
}

see examples/folders


Quick Run Down for WebSocket

Raw WebSocket mocking routes connections by URL path:

  • Define a path (exact string, regex, or Express-style params)
  • Point to a handler file exporting any combination of lifecycle hooks
  • The handler receives the raw ws.WebSocket connection object directly — no protocol abstraction

Handler hooks

| Hook | Signature | When it fires | |---|---|---| | onOpen | (ws, req) | Client connects. req.params is populated for params matchType routes. | | onMessage | (ws, data, isBinary) | Client sends a message. | | onClose | (ws, code, reason) | Connection closes. | | onError | (ws, err) | A socket error occurs. |

All hooks are optional.


Quick Run Down for Socket.IO

Socket.IO mocking supports inbound event handling:

  • Define an event name (exact or regex match)
  • Point to a handler file exporting functions named after events
  • When a client emits the event, the matching function runs

Getting Started with HTTP

Install

npm install -g mocwai

Example Config

Create a file ./config.json:

{
  "http": [
    {
      "method": "get",
      "path": "/users/1",
      "matchType": "string",
      "contentType": "application/json",
      "inline": {
        "id": 1,
        "name": "foo"
      }
    },
    {
      "method": "get",
      "path": "/index.html",
      "matchType": "string",
      "contentType": "text/html",
      "inline": "<html><body><h1>my static content</h1></body></html>"
    }
  ]
}

Validate

mocwai validate ./config.json

Serve

mocwai serve -c ./config.json

Call

curl http://localhost:8080/users/1

Getting Started with Socket.IO

Example Config

{
  "socket": [
    {
      "direction": "inbound",
      "event": "ping",
      "matchType": "string",
      "handler": "./handlers/ping.js"
    }
  ]
}

Example Handler

handlers/ping.js

module.exports = {
  ping: (socket, data) => {
    console.log('received ping:', data);
    socket.emit('pong', { ok: true });
  }
};

Connect and Emit

Use a Socket.IO client to emit a ping event.


Getting Started with WebSocket

Example Config

{
  "websocket": [
    {
      "path": "/ws/echo",
      "matchType": "string",
      "handler": "./handlers/echo.js"
    },
    {
      "path": "/ws/chat/:room",
      "matchType": "params",
      "handler": "./handlers/chat.js"
    }
  ]
}

Example Handler

handlers/echo.js

module.exports = {
  onOpen: (ws) => {
    ws.send('connected');
  },
  onMessage: (ws, data, isBinary) => {
    ws.send(data, { binary: isBinary }); // echo back
  },
};

handlers/chat.js — using req.params from a params route:

module.exports = {
  onOpen: (ws, req) => {
    ws.send(JSON.stringify({ joined: req.params.room }));
  },
  onMessage: (ws, data) => {
    // broadcast to other clients in the same room...
  },
};

Connect

Use any standard WebSocket client:

# wscat (npm install -g wscat)
wscat -c ws://localhost:8080/ws/echo

Or the browser's native WebSocket API — no Socket.IO client required.

see examples/web-socket


More Info

See the ./examples folder in the repository for more sample configs and handlers.