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 集成。

Hoppscotch 横幅

Hoppscotch 图标

核心概念 #

  • 工作区:面向团队的容器,用于集合、环境和共享资源

  • 集合:具有文件夹层级结构的 API 请求的有组织组合

  • 环境:用于开发、预发布和生产环境的变量存储

  • 预请求脚本:通过 pw 对象在每个请求之前执行的 JavaScript 片段

  • 测试:使用相同的 pw 脚本 API 进行响应后的断言

  • 拦截器:用于本地主机测试的浏览器扩展或基于代理的请求拦截

安装与设置 #

方法 1:网页版应用(最快 — 30 秒) #

无需安装。

导航到 [hoppscotch。

io](https://hoppscotch.io) 并立即开始发送请求。

由于服务工作者的缓存,该应用在首次加载后可以离线使用。

Hoppscotch 标志

方法二:桌面应用 #

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 |

|

💬 留言讨论