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

apigrip

v0.15.0

Published

A spec-first, read-only OpenAPI client for developers

Downloads

2,321

Readme

Apigrip

A spec-first, read-only OpenAPI client for developers who generate their API specs from code.

The spec file on disk is the only source of truth. It is never imported, copied, or converted. When it changes (because you regenerated it, switched branches, or pulled), the tool reflects the changes immediately.

Apigrip demo

Quick start

# Install globally
npm install -g apigrip

# Bookmark a project and start the UI
apigrip projects add /path/to/your/api
apigrip serve

Or run from inside a project directory (auto-detects the spec):

cd /path/to/your/api
apigrip serve

Open http://127.0.0.1:3000 in your browser.

Requirements

  • Node.js 20+
  • curl 7.70+ (for --write-out JSON format)

Features

  • Browse endpoints from any OpenAPI 2.0, 3.0.x, or 3.1.x spec
  • Send requests via curl subprocess with full curl -v level detail
  • Live reload on spec changes, git branch switches, and $ref dependency updates (web UI and MCP)
  • Parameter persistence across restarts (auto-saved per project, per endpoint)
  • Named environments with {{ variable }} syntax resolved at send time
  • .apigrip.json project config for team-shared environment seeding and spec path override
  • Git status bar showing branch, commit, and dirty/clean state
  • Ctrl+P command palette with fuzzy search across projects and endpoints
  • Response schema validation against the spec
  • Dracula dark theme by default, light mode available
  • MCP server for AI coding assistants
  • Electron desktop app (standalone window, no browser needed)

CLI

# Start the web UI
apigrip serve                                    # loads last bookmarked project
apigrip serve --port 8080 --open                 # custom port, open browser
apigrip serve --project /path/to/api             # explicit project

# Send requests from the terminal
apigrip send GET /users                          # basic request
apigrip send POST /users -d '{"name": "John"}'   # with body
apigrip send GET /users/{id} --pathParam id=42   # path param
apigrip send GET /users -e Staging --verbose     # use named environment
apigrip send GET /users --dry-run                # print without sending
apigrip send GET /users --curl                   # print curl command only

# Generate curl command (shorthand for send --curl)
apigrip curl GET /users -e Production

# List endpoints
apigrip list                                     # grouped by tag
apigrip list --search "auth" --json              # fuzzy search, JSON output

# Show endpoint details
apigrip show GET /users                          # parameters, schemas, responses
apigrip show POST /users --json                  # full JSON output

# Print parsed spec
apigrip spec                                     # dereferenced JSON
apigrip spec --raw                               # original file as-is

# Manage projects
apigrip projects                                 # list bookmarks
apigrip projects add ./my-api                    # bookmark a directory
apigrip projects remove my-api                   # remove bookmark

# Manage environments
apigrip env                                      # list environments
apigrip env show Staging                         # show variables
apigrip env set Staging api_key "sk-123"         # set a variable
apigrip env delete Staging api_key               # delete a variable
apigrip env import envs.json                     # import from JSON file
apigrip env import staging.json --import-name Staging  # into named env

# View last cached response
apigrip last                                     # list all cached endpoints
apigrip last GET /users                          # show last response body
apigrip last GET /users --json                   # full JSON output

# MCP server (for AI assistants)
apigrip mcp --project /path/to/api

Shell completion

# Bash — add to ~/.bashrc
eval "$(apigrip completion --shell bash)"

# Zsh — add to ~/.zshrc
eval "$(apigrip completion --shell zsh)"

# Auto-detects shell if --shell is omitted
eval "$(apigrip completion)"

Exit codes

| Code | Meaning | |------|---------| | 0 | Success (HTTP 4xx/5xx responses are still exit 0) | | 1 | Network error (DNS, connection refused, timeout) | | 2 | Spec parse error | | 3 | Endpoint not found |

Project context

CLI commands auto-detect the project from the current working directory:

  1. If --project or --spec is passed, use that
  2. If cwd is inside a bookmarked project, use it
  3. If cwd contains an OpenAPI spec file, use it directly
  4. Otherwise, error

The serve command has additional fallbacks: if cwd is a git repo with a spec, it uses that. Otherwise it loads the first bookmarked project. Opening a project in the web UI automatically bookmarks it.

Web UI

Two-panel layout: request on the left, response on the right.

Left panel -- endpoint browser (tag view or path tree view), server selector, parameter inputs, request body editor, send button.

Right panel -- status badge, timing, response body (pretty-printed), headers, verbose curl -v output, copyable curl command.

Keyboard shortcuts: Ctrl+P (command palette), Ctrl+O (open project), Ctrl+E (environment editor), Ctrl+Enter (send request), Ctrl+Shift+L (toggle theme).

Desktop app (Electron)

npm run electron:dev           # launch in development
npm run electron:build         # package distributable

The Electron wrapper runs the Express server in-process and opens the UI in a native window. Same features as the web UI, no browser required.

Project config (.apigrip.json)

Optional checked-in file at your project root that seeds environments for the team:

{
  "spec": "docs/openapi.yaml",
  "active_environment": "staging",
  "environments": {
    "base": { "base_url": "https://api.example.com" },
    "staging": { "base_url": "https://staging.example.com" },
    "production": { "base_url": "https://prod.example.com" }
  }
}

All fields are optional. The seed algorithm is non-destructive: it only adds environments that don't already exist in the user's config and never overwrites existing values. The spec field overrides automatic spec discovery.

Environments

Environments are named sets of key-value pairs stored per project in the config directory (never in your project).

Base Environment     ->  base_url=http://localhost:8080, api_version=v1
  + Staging          ->  base_url=https://staging.example.com, auth_token=sk-...
  + Production       ->  base_url=https://api.example.com, auth_token=pk-...

Reference variables anywhere: server URL, parameters, headers, request body. They resolve at send time.

Reserved keys: timeout (integer, seconds -- default 30), insecure (boolean -- passes --insecure to curl).

Library API

Use apigrip programmatically in your own scripts and tools:

// ESM
import { loadSpec, send, validateBody } from 'apigrip';

// CommonJS
const { loadSpec, send } = await require('apigrip');

Quick examples

// Load and inspect a spec
const { spec, endpoints } = await loadSpec('./my-api/');
console.log(`${endpoints.length} endpoints found`);

// Send a request with full validation
const res = await send('./my-api/', 'GET', '/users', {
  params: { query: { limit: '10' } },
  env: 'staging',
  projectDir: './my-api/',
});
console.log(res.status, res.validation);

// Retrieve last cached response
import { loadLastResponse } from 'apigrip';
const cached = loadLastResponse('./my-api/', 'GET', '/users');

All exports

| Category | Functions | |----------|-----------| | Spec | discoverSpec, parseSpec, extractEndpoints, getEndpointDetails, getRefDeps | | Request | buildUrl, buildCurlArgs, executeCurl, cancelRequest, checkCurl, shellQuote | | Environment | loadEnvironments, saveEnvironments, resolveEnvironment, resolveVariables, resolveAllParams, getConfigDir, getProjectHash | | Validation | validateBody, validateResponse | | Storage | loadParams, saveParams, saveLastResponse, loadLastResponse, loadProjects, addProject, removeProject, loadPreferences, savePreferences, getGitInfo | | Project config | loadProjectConfig, applyProjectConfig, getSpecOverride | | Convenience | loadSpec, send |

Direct core module access is also available: import { parseSpec } from 'apigrip/core/spec-parser.js'

MCP server

Expose the spec to AI coding assistants via the Model Context Protocol:

{
  "mcpServers": {
    "api": {
      "command": "apigrip",
      "args": ["mcp", "--project", "/path/to/api"]
    }
  }
}

Tools: list_endpoints, get_endpoint, get_schema, validate_request_body, send_request, get_last_response, list_environments, get_environment, get_project_path, get_spec_path

Resources: spec://parsed, project://info

The MCP server watches the spec file and auto-reloads when it changes, so tools always return current data.

Project structure

apigrip/
├── cli/              CLI entry point and commands
│   ├── index.js      Yargs command registration
│   ├── output.js     CLI formatting (table, JSON, color)
│   ├── resolve-project.js  Shared project context resolution
│   └── commands/     serve, send, curl, list, show, spec, projects, env, last, mcp
├── core/             Shared logic (spec parsing, curl, environments, persistence)
│   ├── spec-discovery.js    Find OpenAPI spec in a directory
│   ├── spec-parser.js       Parse/dereference specs (2.0, 3.0, 3.1)
│   ├── curl-builder.js      Build curl args array
│   ├── curl-executor.js     Execute curl subprocess
│   ├── env-resolver.js      Load/merge environments, resolve {{ variables }}
│   ├── git-info.js          Git status via CLI
│   ├── params-store.js      Per-endpoint parameter persistence
│   ├── response-store.js    Per-endpoint response caching
│   ├── projects-store.js    Project bookmark CRUD
│   ├── preferences-store.js Global + per-project preferences
│   ├── project-config.js    .apigrip.json loader and environment seeder
│   └── schema-validator.js  JSON Schema validation (ajv)
├── electron/         Electron desktop wrapper
│   └── main.js       Main process (Express + BrowserWindow)
├── lib/              Programmatic library API
│   ├── index.js      ESM entrypoint (re-exports + loadSpec, send)
│   └── index.cjs     CJS compatibility wrapper
├── mcp/              MCP server wiring
│   └── server.js     Tools + resources -> core modules
├── server/           Express server, routes, SSE, file watcher
│   ├── index.js      Server factory, route mounting
│   ├── spec-watcher.js  Chokidar watchers (spec, $ref deps, .git/, .apigrip.json)
│   └── routes/       REST endpoint handlers
├── client/           React frontend (Vite build)
│   ├── components/   TopBar, EndpointList, RequestPanel, ResponsePanel, ...
│   ├── lib/          api.js (HTTP client), sse.js (SSE client)
│   └── styles/       CSS variables (Dracula palette), layout, components
└── test/             Node.js built-in test runner
    ├── core/         Unit tests for all core modules
    ├── cli/          CLI command tests
    ├── server/       Route + SSE integration tests
    ├── mcp/          MCP server tests
    └── fixtures/     Test specs (apigrip-openapi.yaml, petstore-2.0.json)

Config is stored at $XDG_CONFIG_HOME/apigrip/ (or ~/.config/apigrip/). Project directories are never written to.

Testing

npm test

Runs 814 tests using Node's built-in test runner (node --test). The test suite uses the tool's own OpenAPI spec as a fixture (self-referential testing).

License

ISC