
Research
Node.js Fixes AsyncLocalStorage Crash Bug That Could Take Down Production Servers
Node.js patched a crash bug where AsyncLocalStorage could cause stack overflows to bypass error handlers and terminate production servers.
The API client that lives in your terminal (and your git repo).
Stop clicking through heavy Electron apps just to send a JSON body. yapi is a CLI-first, offline-first, git-friendly API client for HTTP, gRPC, and TCP. It uses simple YAML files to define requests, meaning you can commit them, review them, and run them anywhere.
Try the Playground | View Source
macOS:
curl -fsSL https://yapi.run/install/mac.sh | bash
Linux:
curl -fsSL https://yapi.run/install/linux.sh | bash
Windows (PowerShell):
irm https://yapi.run/install/windows.ps1 | iex
Using Homebrew (macOS):
brew tap jamierpond/yapi
brew install --cask yapi
Using Go:
go install yapi.run/cli/cmd/yapi@latest
From Source:
git clone https://github.com/jamierpond/yapi
cd yapi
make install
Create a request file (e.g., get-user.yapi.yml):
yapi: v1
url: https://jsonplaceholder.typicode.com/users/1
method: GET
Run it:
yapi run get-user.yapi.yml
See the magic: You get a beautifully highlighted, formatted response.
Note: The
yapi: v1version tag is required at the top of all config files. This enables future schema evolution while maintaining backwards compatibility.
yapi speaks many protocols. Here is how you define them.
Chain multiple requests together, passing data between steps. Build authentication flows, integration tests, or multi-step workflows.
yapi: v1
chain:
# Step 1: Login and get token
- name: login
url: https://api.example.com/auth/login
method: POST
body:
username: "dev_sheep"
password: ${PASSWORD} # from environment
expect:
status: 200
assert:
- .token != null
# Step 2: Create a post using the token
- name: create_post
url: https://api.example.com/posts
method: POST
headers:
Authorization: Bearer ${login.token}
body:
title: "Hello World"
tags:
- cli
- testing
author:
id: 123
active: true
expect:
status: 201
assert:
- .id != null
- .title == "Hello World"
Key features:
${step_name.field} syntax${login.data.token}Manage multiple environments (dev, staging, prod) with a single config file. Create a yapi.config.yml:
yapi: v1
default_environment: local
environments:
local:
url: http://localhost:3000
vars:
API_KEY: dev_key_123
prod:
url: https://api.example.com
vars:
API_KEY: ${PROD_API_KEY} # from shell env
env_file: .env.prod # load vars from file
Then reference in your requests:
yapi: v1
url: ${url}/api/v1/users
method: GET
headers:
Authorization: Bearer ${API_KEY}
Switch environments: yapi run my-request.yapi.yml -e prod
No more escaping quotes in curl. Just clean YAML.
yapi: v1
url: https://api.example.com/posts
method: POST
content_type: application/json
body:
title: "Hello World"
tags:
- cli
- testing
Validate complex response structures with JQ-powered assertions.
yapi: v1
url: https://api.example.com/users
method: GET
expect:
status: 200 # or [200, 201] for multiple valid codes
assert:
- . | length > 0 # array has items
- .[0].email != null # first item has email
- .[] | .active == true # all items are active
Don't grep output. Filter it right in the config.
yapi: v1
url: https://jsonplaceholder.typicode.com/users
method: GET
# Only show me names and emails, sorted by name
jq_filter: "[.[] | {name, email}] | sort_by(.name)"
Stop hunting for .proto files. If your server supports reflection, yapi just works.
yapi: v1
url: grpc://localhost:50051
service: helloworld.Greeter
rpc: SayHello
body:
name: "yapi User"
First-class support for queries and variables.
yapi: v1
url: https://countries.trevorblades.com/graphql
graphql: |
query getCountry($code: ID!) {
country(code: $code) {
name
capital
}
}
variables:
code: "BR"
wait_forPoll an endpoint until conditions are met. Perfect for async jobs, webhooks, and eventual consistency.
Fixed Period Polling:
yapi: v1
url: ${url}/jobs/${job_id}
method: GET
wait_for:
until:
- .status == "completed"
period: 2s
timeout: 60s
Exponential Backoff:
yapi: v1
url: ${url}/jobs/${job_id}
method: GET
wait_for:
until:
- .status == "completed"
backoff:
seed: 1s
multiplier: 2
timeout: 60s
Backoff waits: 1s -> 2s -> 4s -> 8s... until timeout.
In Chains - Async Job Workflow:
yapi: v1
chain:
- name: create_job
url: ${url}/jobs
method: POST
body:
type: "data_export"
expect:
status: 202
- name: wait_for_job
url: ${url}/jobs/${create_job.job_id}
method: GET
wait_for:
until:
- .status == "completed" or .status == "failed"
period: 2s
timeout: 300s
expect:
assert:
- .status == "completed"
- name: download
url: ${wait_for_job.download_url}
method: GET
output_file: ./export.csv
Don't remember the file name? Just run yapi without arguments.
yapi
This launches the Interactive TUI. You can fuzzy-search through all your .yapi.yml files in the current directory (and subdirectories) and execute them instantly.
For a richer CLI experience, source the yapi shell helper in your .zshrc:
# Add to ~/.zshrc
YAPI_ZSH="/path/to/yapi/bin/yapi.zsh" # or wherever you installed yapi
[ -f "$YAPI_ZSH" ] && source "$YAPI_ZSH"
# Optional: short alias
alias a="yapi"
This enables:
↑ to re-run it instantly.Note: Requires
jqto be installed.
Tired of Alt-Tab -> Up Arrow -> Enter? Use watch mode to re-run the request every time you save the file.
yapi watch ./my-request.yapi.yml
Stress test entire workflows with concurrent execution. Not just individual requests - stress test multi-step chains, auth flows, and complex scenarios. Perfect for finding bottlenecks in real-world usage patterns.
# Stress test an auth flow: login -> create post -> fetch results
yapi stress auth-flow.yapi.yml -n 1000 -p 50
# Run a multi-step workflow for 30 seconds
yapi stress my-workflow.yapi.yml -d 30s -p 10
# Load test against production
yapi stress checkout-flow.yapi.yml -e prod -n 500 -p 25
Options:
-n, --num-requests - Total number of workflow executions (default: 100)-p, --parallel - Number of concurrent workflow executions (default: 1)-d, --duration - Run for a specific duration (e.g., 10s, 1m) - overrides num-requests-e, --env - Target a specific environment from yapi.config.yml-y, --yes - Skip confirmation promptKey advantage: Each parallel execution runs the entire chain - login, get token, make authenticated request, etc. This tests your API under realistic load, not just isolated endpoints.
Run your yapi tests automatically in GitHub Actions with service orchestration and health checks built-in.
name: Integration Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Run Yapi Integration Tests
uses: jamierpond/yapi/action@0.X.X # specify version, or use @main for latest
with:
# Start your service in the background
start: npm run dev
# Wait for it to be healthy
wait-on: http://localhost:3000/health
# Run your test suite
command: yapi test ./tests -a
Features:
Multiple services example:
- uses: jamierpond/yapi/action@0.X.X # specify version, or use @main for latest
with:
start: |
docker-compose up -d
pnpm --filter api dev
wait-on: |
http://localhost:8080/health
http://localhost:3000/ready
command: yapi test ./integration -a
See the action documentation for more options.
Run tests locally with automatic server lifecycle management. Configure in yapi.config.yml:
yapi: v1
test:
start: "npm run dev"
wait_on:
- "http://localhost:3000/healthz"
timeout: 60s
parallel: 8
environments:
local:
url: http://localhost:3000
Now yapi test will automatically:
Supported health check protocols:
http:// / https:// - HTTP health endpoints (expects 2xx)grpc:// / grpcs:// - gRPC health check protocoltcp:// - TCP connection check (databases, etc.)CLI flags:
yapi test ./tests # Uses config from yapi.config.yml
yapi test ./tests --no-start # Skip server startup (already running)
yapi test ./tests --start "npm start" --wait-on "http://localhost:4000/health"
yapi test ./tests --verbose # See server output
Unlike other API clients, yapi ships with a full LSP implementation out of the box. Your editor becomes an intelligent API development environment with real-time validation, autocompletion, and inline execution.
Install the official extension from VS Code Marketplace or Open VSX:
Features:
Cmd+Enter (Mac) or Ctrl+Enter (Windows/Linux) - execute requests without leaving your editor${VAR} to see environment variable statusThe extension automatically detects .yapi.yml files and activates the language server. No configuration needed.
yapi was built with Neovim in mind. First-class support via lua/yapi_nvim:
-- lazy.nvim
{
dir = "~/path/to/yapi/lua/yapi_nvim",
config = function()
require("yapi_nvim").setup({
lsp = true, -- Enables the yapi Language Server
pretty = true, -- Uses the TUI renderer in the popup
})
end
}
Commands:
:YapiRun - Execute the current buffer:YapiWatch - Open a split with live reloadThe LSP communicates over stdio and works with any editor that supports the Language Server Protocol:
yapi lsp
| Feature | Description |
|---|---|
| Real-time Validation | Errors and warnings as you type, with precise line/column positions |
| Intelligent Autocompletion | Context-aware suggestions for keys, HTTP methods, content types |
| Hover Info | Hover over ${VAR} to see environment variable status |
| Go to Definition | Jump to referenced chain steps and variables |
Create a yapi.config.yml file in your project root to manage multiple environments:
yapi: v1
default_environment: local
environments:
local:
url: http://localhost:8080
vars:
API_KEY: local_test_key
DEBUG: "true"
staging:
url: https://staging.api.example.com
vars:
API_KEY: ${STAGING_KEY} # From shell environment
DEBUG: "false"
prod:
url: https://api.example.com
vars:
API_KEY: ${PROD_KEY}
DEBUG: "false"
Then reference these variables in your request files:
yapi: v1
url: ${url}/users
method: GET
headers:
Authorization: Bearer ${API_KEY}
X-Debug: ${DEBUG}
Switch environments with the -e flag:
yapi run get-users.yapi.yml -e staging
Benefits:
cmd/yapi: The main CLI entry point.internal/executor: The brains. HTTP, gRPC, TCP, and GraphQL logic.internal/tui: The BubbleTea-powered interactive UI.examples/: Look here for a ton of practical YAML examples!webapp/: The Next.js code for yapi.run.Found a bug? Want to add WebSocket support? PRs are welcome!
make build to ensure it compiles.make test to run the suite.main - Stable releases. All stable version tags (e.g., v0.5.0) are cut from this branch.
next - Unstable/integration branch. Every push to next triggers an automatic pre-release with version format vX.Y.Z-next.<short-hash>. These releases:
.vsix filenext.yapi.runMade with ☕ and Go.
FAQs
Unknown package
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Node.js patched a crash bug where AsyncLocalStorage could cause stack overflows to bypass error handlers and terminate production servers.

Research
/Security News
A malicious Chrome extension steals newly created MEXC API keys, exfiltrates them to Telegram, and enables full account takeover with trading and withdrawal rights.

Security News
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.