Hoppscotch:79,200 个 GitHub 星标——开源 API 开发平台,与
Hoppscotch (HOPP) is an open-source API development ecosystem. Docker, GitHub Actions, Node.js, Vue.js compatible. Covers hoppscotch tutorial, self-hosting, CLI automation, and comparison vs alternatives.
- MIT
- 更新于 2026-05-19
{{< 资源信息 >}}
引言 #
每一个曾经等待 Postman 启动八秒、盯着冻结的同步栏,或者不小心将生产凭证提交到共享工作区的开发者都知道这种痛苦。
API 测试工具已经变得臃肿、被企业锁定,并且对个人开发者和小团队越来越不友好。
在2026年,越来越多的工程师正在转向Hoppscotch——一个拥有79,200个GitHub星标的开源API开发生态系统,5。
每月处理900万次请求,并且秉持这样一种理念:API工具应该快速、免费,并且完全由你掌控。
本文是一篇 Hoppscotch 教程,涵盖安装、Docker 设置、CLI 自动化,以及与 Postman、Insomnia 和 Bruno 的数据驱动比较。
什么是 Hoppscotch? #
Hoppscotch 是一个开源的、基于网页的 API 开发平台,作为 Postman 和 Insomnia 的轻量级替代方案构建。
它支持 REST、GraphQL、WebSocket、SSE、Socket。
IO 和 MQTT 协议,完全在浏览器中作为 PWA 运行,提供桌面应用程序,并且可以通过 Docker 自托管以实现完整的数据主权。
成立于2019年,并获得MIT许可,它已经发展成为GitHub上最受欢迎的开发者工具仓库之一,拥有350多名贡献者,并且发布节奏为每周更新一次。
Hoppscotch 如何工作 #
架构概览 #
Hoppscotch 采用模块化 monorepo 架构。
前端是用 Vue 3、Vite 和 TypeScript 构建的。
后端使用 NestJS 并结合 PostgreSQL 进行数据持久化。
该桌面应用使用 Tauri(基于 Rust)封装了网页界面,从而生成了一个不到 10 MB 的桌面二进制文件——仅为基于 Electron 的竞争对手的一小部分。
一个由 Rust 提供支持的命令行工具实现了无头自动化和 CI/CD 集成。
!
!
核心概念 #
-
工作区:面向团队的容器,用于集合、环境和共享资源
-
集合:具有文件夹层级结构的 API 请求的有组织组合
-
环境:用于开发、预发布和生产环境的变量存储
-
预请求脚本:通过
pw对象在每个请求之前执行的 JavaScript 片段 -
测试:使用相同的
pw脚本 API 进行响应后的断言 -
拦截器:用于本地主机测试的浏览器扩展或基于代理的请求拦截
安装与设置 #
方法 1:网页版应用(最快 — 30 秒) #
无需安装。
导航到 [hoppscotch。
io](https://hoppscotch.io) 并立即开始发送请求。
由于服务工作者的缓存,该应用在首次加载后可以离线使用。
!
方法二:桌面应用 #
a
s
h
# macOS (Homebrew)
brew install --cask hoppscotch
# Windows (Winget)
winget install Hoppscotch.Hoppscotch
# Linux (Flatpak)
flatpak install flathub io.hoppscotch.Hoppscotch
方法 3:命令行工具 #
a
s
h
# Install prerequisites (Debian/Ubuntu)
sudo apt-get install -y python3 g++ build-essential
# Install the CLI globally
npm i -g @hoppscotch/cli
# Verify installation
hopp --version
# Output: 0.31.2
方法 4:Docker 自托管(生产环境) #
a
s
h
# Pull the AIO image
docker pull hoppscotch/hoppscotch:latest
# Create environment file
cat > .env << 'EOF'
# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/hoppscotch
# JWT Secrets
JWT_SECRET=$(openssl rand -hex 32)
REFRESH_TOKEN_SECRET=$(openssl rand -hex 32)
# Base URLs
REDIRECT_URL=http://localhost:3000
ADMIN_URL=http://localhost:3100
BACKEND_URL=http://localhost:3170
# Session Secret
SESSION_SECRET=$(openssl rand -hex 32)
EOF
# Run the AIO container
docker run -d \
-p 3000:3000 \
-p 3100:3100 \
-p 3170:3170 \
--env-file .env \
--restart unless-stopped \
--name hoppscotch \
hoppscotch/hoppscotch:latest
Docker Compose(推荐用于生产环境) #
a
m
l
# docker-compose.yml
version: "3.8"
services:
hoppscotch:
image: hoppscotch/hoppscotch:2026.4.1
container_name: hoppscotch-app
ports:
- "3000:3000" # Main app
- "3100:3100" # Admin dashboard
- "3170:3170" # Backend API
env_file: .env
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
networks:
- hoppscotch-net
postgres:
image: postgres:16-alpine
container_name: hoppscotch-db
environment:
POSTGRES_DB: hoppscotch
POSTGRES_USER: hoppscotch
POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U hoppscotch"]
interval: 10s
timeout: 5s
retries: 5
networks:
- hoppscotch-net
volumes:
postgres_data:
driver: local
networks:
hoppscotch-net:
driver: bridge
部署以启动堆栈:
a
s
h
docker compose up -d
# Verify all services are healthy
docker compose ps
# View logs
docker compose logs -f hoppscotch
对于准备在 VPS 上部署的团队,DigitalOcean 为新用户提供 200 美元的积分 —— 足够在 2 vCPU / 2 GB 内存的 droplet 上运行 Hoppscotch 实例几个月。
与流行工具的集成 #
GitHub Actions CI/CD 管道 #
a
m
l
# .github/workflows/api-tests.yml
name: API Tests with Hoppscotch CLI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
api-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install Hoppscotch CLI
run: npm i -g @hoppscotch/cli
- name: Verify CLI version
run: hopp --version
- name: Start test server
run: |
npm run start:test &
npx wait-on http://localhost:8080 --timeout 30000
- name: Run API collection tests
run: |
hopp test collections/api-tests.json \
-e environments/test.json \
--reporter-junit test-results.xml \
--delay 500
env:
API_BASE_URL: http://localhost:8080
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: api-test-results
path: test-results.xml
节点。 #
JS 应用集成
i
p
t
// scripts/run-api-tests.js
const { execSync } = require("child_process");
const path = require("path");
const collectionPath = path.join(__dirname, "../collections");
const envPath = path.join(__dirname, "../environments");
function runTests(environment) {
const command = [
"hopp test",
`"${collectionPath}/core-apis.json"`,
`-e "${envPath}/${environment}.json"`,
"--reporter-junit",
`"reports/${environment}-results.xml"`,
].join(" ");
console.log(`Running tests against ${environment}...`);
execSync(command, { stdio: "inherit" });
}
// Run against staging before production deploy
runTests("staging");
Vue。 #
js 前端代理配置
i
p
t
// vite.config.js
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
"/api": {
target: process.env.API_BASE_URL || "http://localhost:3170",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
});
OAuth2 令牌刷新预请求脚本 #
i
p
t
// Hoppscotch pre-request script
const token = pw.env.get("AUTH_TOKEN");
const expiry = pw.env.get("TOKEN_EXPIRY");
if (!token || Date.now() > Number(expiry)) {
const res = await pw.api.post("https://auth.example.com/oauth/token", {
body: JSON.stringify({
client_id: pw.env.get("CLIENT_ID"),
client_secret: pw.env.get("CLIENT_SECRET"),
grant_type: "client_credentials",
}),
headers: {
"Content-Type": "application/json",
},
});
const data = JSON.parse(res.body);
pw.env.set("AUTH_TOKEN", data.access_token);
pw.env.set("TOKEN_EXPIRY", String(Date.now() + data.expires_in * 1000));
}
// Apply token to current request
pw.headers.set("Authorization", `Bearer ${pw.env.get("AUTH_TOKEN")}`);
响应后的测试断言 #
i
p
t
// Hoppscotch test script
pw.test("Status code is 200", () => {
pw.expect(pw.response.status).toBe(200);
});
pw.test("Response has correct content type", () => {
pw.expect(pw.response.headers["content-type"]).toInclude("application/json");
});
pw.test("Response body contains user ID", () => {
const json = pw.response.json();
pw.expect(json).toHaveProperty("id");
pw.expect(json.id).toBeGreaterThan(0);
});
pw.test("Response time is acceptable", () => {
pw.expect(pw.response.time).toBeLessThan(500);
});
基准测试 / 真实世界用例 #
性能比较 #
| 指标 | Hoppscotch | Postman | Insomnia | Bruno |
|
💬 留言讨论