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

snaperro

v1.1.14

Published

🐕 Record real API responses, replay them anytime. Visual control included.

Downloads

971

Readme

snaperro

A mock proxy server that records and replays responses from multiple APIs to streamline development and testing.

Name Origin

  • snap: snapshot, quickly capture
  • perro: Spanish for "dog"
  • The image of "a faithful dog that fetches data"

Features

  • 4 Modes: Proxy (passthrough) / Record (capture) / Mock (playback) / Smart (auto)
  • Parameter Matching: Accurate matching by path parameters and query parameters
  • State Persistence: Mode and scenario settings persist across server restarts
  • TypeScript Configuration: Type-safe configuration files

Why snaperro?

Are you facing these problems during development?

  • Depending on multiple APIs, making environment setup difficult
  • Local development stops due to external API outages
  • Preparing test data is tedious
  • "I want to reproduce this state" but manually operating each time is a hassle

snaperro is a mock proxy server that saves API responses as "snapshots" and can replay them anytime.


For Users

Quick Start

# Install
npm install -D snaperro

# Initialize (generates .snaperro/, snaperro.config.ts)
npx snaperro init

# Start server
npx snaperro start

Demo

We provide a demo environment where you can experience snaperro in action.

npx snaperro demo

Your browser will open http://localhost:3333/__snaperro__/demo.

Features You Can Try

| Feature | Description | |---------|-------------| | Mode Switching | Experience the differences between Proxy/Record/Mock modes | | Path Parameter | Save and return different responses for each ID with /users/:id | | Query String | Save and return different responses for each query with /posts?userId=1 | | Nested Resource | Fetch nested resources with /posts/:id/comments |

For detailed management (scenarios/files/JSON editing), use the GUI (/__snaperro__/client).

Built-in APIs

The following APIs are available without configuration:

| API | Target | Routes | |-----|--------|--------| | jsonPlaceholder | https://jsonplaceholder.typicode.com | /users, /posts, /comments, etc. |

These are used by the demo page and can be overridden in your config if needed.

Web GUI

Intuitively operate snaperro from your browser.

Access

http://localhost:3333/__snaperro__/client

The browser opens automatically when the server starts.

Features

| Feature | Description | |---------|-------------| | Mode Switch | Switch between Proxy/Record/Mock with one click | | Scenario Management | Create, delete, duplicate, and rename scenarios | | File Management | List and delete recorded JSON files | | JSON Editor | View and edit responses | | Real-time Updates | Instantly reflect state changes via SSE |

Configuration File

snaperro.config.ts

import { defineConfig } from 'snaperro'

export default defineConfig({
  port: 3333,

  apis: {
    userService: {
      name: "User Service",
      target: "https://api.example.com",
      headers: {
        "X-Api-Key": process.env.API_KEY!,
      },
      routes: [
        "/api/users",
        "/api/users/:id",
        "/api/users/:id/profile",
      ],
    },

    orderService: {
      name: "Order Service",
      target: "https://order-api.example.com",
      routes: [
        "/api/orders",
        "/api/orders/:id",
        "/api/users/:userId/orders",
      ],
    },
  },
})

.env

# Sensitive information such as API keys
API_KEY=your-api-key-here

Configuration Options

| Option | Type | Description | |--------|------|-------------| | port | number | Server port (default: 3333) | | filesDir | string | File storage directory (default: .snaperro/files) | | mockFallback | string | Fallback behavior when mock file is not found (default: "404") | | maskRequestHeaders | string[] | Headers to mask when recording (applied to all APIs) | | apis | object | API definitions object |

API Definition

| Option | Type | Required | Description | |--------|------|----------|-------------| | name | string | Yes | API display name | | target | string | Yes | Proxy target URL | | routes | string[] | Yes | Matching route patterns | | headers | object | No | Headers to add | | maskRequestHeaders | string[] | No | Headers to mask when recording |

Upstream Proxy

If you're behind a corporate proxy, configure upstream proxy settings:

Via config file:

export default defineConfig({
  upstreamProxy: {
    url: "http://proxy.company.com:8080",
  },
  // ...
})

Via environment variable:

export HTTPS_PROXY=http://proxy.company.com:8080
# or with authentication
export HTTPS_PROXY=http://username:[email protected]:8080

Config file takes priority over environment variables.

Important: When using an upstream proxy, add localhost to NO_PROXY to ensure local requests bypass the proxy:

export NO_PROXY=localhost,127.0.0.1

CLI Commands

| Command | Description | |---------|-------------| | npx snaperro init | Initialize project | | npx snaperro start | Start server | | npx snaperro start -p 4000 | Start with specified port | | npx snaperro demo | Start demo environment | | npx snaperro postman | Export Postman collection |

init Process

  1. Create .snaperro/ directory
  2. Create .snaperro/files/ directory
  3. Create snaperro.config.ts template (if it doesn't exist)
  4. Add .snaperro/ to .gitignore

start Options

| Option | Description | |--------|-------------| | -p, --port <port> | Specify port number | | -c, --config <path> | Specify config file path | | -e, --env <path> | Specify env file path (default: .env in config directory) | | -v, --verbose | Show detailed logs |

4 Modes

| Mode | Real API | Save JSON | Returns | |------|----------|-----------|---------| | Proxy | Access | No | Real response | | Record | Access | Yes | Real response | | Mock | No access | No | Saved JSON | | Smart | Conditional | Conditional | Mock or Real |

Proxy Mode

Connects to the actual API with headers (API Key, etc.) defined in the configuration file.

Request → snaperro → Real API → Response

Record Mode

Connects to the actual API while recording responses to JSON files.

Request → snaperro → Real API → Response
                ↓
           Save to JSON file
  • Same endpoint, same parameters → Overwrite
  • Same endpoint, different parameters → Create new file

Mock Mode

Returns responses from saved JSON files. Does not access the actual API.

Request → snaperro → Search JSON files → Response

Smart Mode

Automatically returns mock data if it exists, otherwise proxies to the real server and records the response.

Request → snaperro → Search mock files
                ↓
         Found? → Yes → Return mock (no API access)
                ↓ No
         Proxy to real API & Record
                ↓
         Return response

This is the recommended mode for daily development:

  • Prevents unnecessary API calls when mock data already exists
  • Automatically records new endpoints
  • Reduces API rate limit concerns

Mock Fallback Behavior

When a mock file is not found, you can configure the fallback behavior with mockFallback:

| Value | Description | |-------|-------------| | "404" | Return 404 error (default) | | "proxy" | Forward request to real server | | "proxy&record" | Forward to real server and record the response |

export default defineConfig({
  mockFallback: "proxy&record",  // Fallback to proxy and record
  // ...
})

What is a Scenario?

A "scenario" is a folder that manages a set of mock data.

.snaperro/
├── state.json              ← Server state (mode, scenario)
└── files/
    ├── normal-full/           ← Scenario "normal-full"
    │   ├── api_users_001.json
    │   ├── api_users_{id}_001.json
    │   └── api_orders_001.json
    ├── empty-data/             ← Scenario "empty-data"
    │   └── api_users_001.json
    └── error-cases/             ← Scenario "error-cases"
        └── api_users_001.json

By switching scenarios, you can use different mock data sets. The previous mode and scenario are restored even after server restart.

Route Definition and Matching

Path Parameters

Define path parameters with :param format.

routes: [
  "/api/users",           // Exact match
  "/api/users/:id",       // :id is a parameter
  "/api/users/:id/orders/:orderId",  // Multiple parameters
]

Matching Examples

routes: ["/api/users/:id"]

| Request | Match | pathParams | |---------|-------|------------| | /api/users/123 | Yes | { id: "123" } | | /api/users/abc | Yes | { id: "abc" } | | /api/users | No | - | | /api/users/123/profile | No | - |

Record Mode Behavior

  • Same parameter request → Overwrite existing file
  • New parameter request → Create new file

Mock Mode Behavior

  • Return file with exact match of path parameters and query parameters
  • Return 404 error if no matching file

File Structure

your-project/
├── snaperro.config.ts     # Config file (Git managed)
├── .env                   # Sensitive info (Not Git managed)
├── .env.example           # Env template (Git managed)
└── .snaperro/             # Recorded data (Not Git managed)
    ├── state.json         # Server state
    └── files/
        ├── normal-full/
        │   ├── api_users_001.json
        │   └── api_users_{id}_001.json
        └── error-cases/
            └── api_users_001.json

SSE (Server-Sent Events)

An SSE endpoint is provided for GUI and clients to detect state changes in real-time.

Endpoint

GET /__snaperro__/events

Verification

# curl
curl -N http://localhost:3333/__snaperro__/events

# Browser console
const es = new EventSource('http://localhost:3333/__snaperro__/events');
es.addEventListener('connected', (e) => console.log(JSON.parse(e.data)));
es.addEventListener('file_created', (e) => console.log(JSON.parse(e.data)));

Event Types

| Event | Description | |-------|-------------| | connected | Connection complete (includes initial state) | | mode_changed | Mode changed | | scenario_changed | Scenario switched | | file_created | File created (during recording) | | file_updated | File updated | | file_deleted | File deleted | | scenario_created | Scenario created | | scenario_deleted | Scenario deleted | | scenario_renamed | Scenario renamed |


For Developers

Local Development (Testing CLI without npm publish)

# 1. Install dependencies
pnpm install

# 2. Build
pnpm build

# 3. Run CLI locally
npx . init
npx . start

During development (run directly without build):

npx tsx src/cli/index.ts init
npx tsx src/cli/index.ts start

Development Commands

When you want to:

| Goal | Command | |------|---------| | Watch code changes during development | pnpm dev | | Build for production | pnpm build | | Run tests | pnpm test | | Run tests in watch mode | pnpm test:watch | | Format code | pnpm format | | Check type errors | pnpm type-check | | Develop GUI | pnpm dev:client | | Build GUI | pnpm build:client | | Develop demo | pnpm dev:demo | | Build demo | pnpm build:demo |

Project Structure

snaperro/
├── cli/                      # CLI commands
│   ├── index.ts
│   └── commands/
│       ├── init.ts
│       ├── postman.ts
│       └── start.ts
├── server/                   # Hono server
│   ├── handlers/
│   │   ├── handler.ts
│   │   ├── proxy.ts
│   │   ├── recorder.ts
│   │   ├── mocker.ts
│   │   └── control-api.ts
│   ├── core/
│   │   ├── config.ts
│   │   ├── state.ts
│   │   ├── storage.ts
│   │   └── matcher.ts
│   └── types/
├── client/                   # React GUI
│   └── src/
├── demo/                     # Demo application
│   └── src/
└── doc/                      # Documentation

Tech Stack

| Category | Choice | |----------|--------| | Server | Hono | | CLI | Commander | | GUI | React + Tailwind CSS | | Schema | Zod | | Logging | Consola | | Path Matching | Picomatch | | Build | tsup, Vite | | Linter/Formatter | Biome | | Test | Vitest |

Requirements

  • Node.js 18 or higher
  • tsx must be installed (peerDependencies)

License

MIT