hoppscotch-backend-git/README.md
tlemesle 0cc7276c23 Auto-generate secrets in per-user state directory
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 16:24:27 +02:00

10 KiB
Raw Permalink Blame History

hoppscotch-backend-git

A self-hosted Hoppscotch-compatible backend that syncs workspace data to a Git repository.

Hoppscotchs official backend keeps collections, environments, and related data in a database. Bruno keeps them as files in Git, but collaboration is async (pull / push / PR) and several team-oriented Git features sit behind a paid plan. This project aims at the gap between those models: live multi-client sync with Git as the durable, reviewable source of truth.

Status: early / work in progress. Phase A (Git store + REST + CLI) and Phase B (auth + personal GraphQL) are implemented. Upstream Hoppscotch is vendored as a Git submodule at hoppscotch-upstream (hoppscotch/hoppscotch).

Why

Teams often want:

  1. A shared API client workspace that updates for everyone without manual export/import
  2. Collections and environments versioned in Git (diff, review, branch, audit)
  3. Self-hosting without a proprietary cloud sync service or per-seat Git UI fees

Exporting Hoppscotch collections into a repo works for occasional backup, not continuous team sync. Bruno solves Git-native storage well, but deliberately has no live sync and gates private remotes / full in-app Git workflows on paid tiers.

hoppscotch-backend-git keeps a Hoppscotch-style backend API while persisting (and syncing) data to Git.

How collaboration works

Each teammate runs this backend on their own machine and points Hoppscotch (Desktop / CLI) at localhost. Identity comes from the local OS account. The shared Git workspace repository is what syncs collections and environments between people — not a central Hoppscotch server.

User A machine                         User B machine
┌─────────────────────┐                ┌─────────────────────┐
│ Hoppscotch Desktop  │                │ Hoppscotch Desktop  │
│         │           │                │         │           │
│ hoppscotch-backend  │                │ hoppscotch-backend  │
│   (local :3200)     │                │   (local :3200)     │
│         │           │                │         │           │
│  GIT_REPO_PATH ────────── push/pull ──────── GIT_REPO_PATH │
└─────────────────────┘       ▲        └─────────────────────┘
                              │
                     shared Git remote
              (collections / environments)

Local-only state (PATs, auto-generated secrets, signing keys, meta.json) lives under a per-user state directory on each machine and is not part of the workspace Git repo:

OS Default state directory
macOS ~/Library/Application Support/hoppscotch-backend-git/
Linux ${XDG_DATA_HOME:-~/.local/share}/hoppscotch-backend-git/

Override with HOPP_STATE_DIR if needed.

Feature comparison

Feature Hoppscotch (cloud / self-host) Bruno Hoppscotch + hoppscotch-backend-git
Live multi-client sync (goal)
Git as primary storage (database) (goal)
Reviewable diffs / PRs for collections ⚠️ via export only (goal)
Offline-first ⚠️ partial (local / desktop) with local backend
Collaboration model Shared backend Git (async) Local backends + shared Git workspace
Private Git remotes without paid client N/A (Pro+ for in-app private remotes) (your Git hosting)
In-app commit / push / branch / merge UI N/A (Pro+ for advanced Git UI) (goal)
Self-hosted, you control the data plane (Community / Enterprise) (local files) (goal)

Notes:

  • Brunos collaboration is Git collaboration, not realtime shared sessions. That is intentional; see Brunos pricing and product FAQ.
  • Official Hoppscotch self-hosting stores data in a database, not a Git repo.
  • Rows marked “(goal)” describe the intended behavior of this project and are not all implemented yet.

Architecture (intended)

Hoppscotch clients (web / desktop / CLI) on each user's machine
        │
        ▼
hoppscotch-backend-git (local)  ←── Hoppscotch-compatible API
        │
        ├── serve that user's Desktop / CLI session
        └── commit / push / pull workspace state to the shared Git repository

Git is the team sync plane and review surface. Each local backend is what that user's clients talk to.

Repository layout

Path Role
hoppscotch-upstream/ Git submodule of official Hoppscotch
src/ Bun + TypeScript backend (REST, auth, GraphQL)
tests/ axios + Hoppscotch CLI integration tests
fixtures/ Sample collection / environment helpers

Development

Clone with submodules:

git clone --recurse-submodules ssh://git@git.kaki87.net:3021/KaKi87/hoppscotch-backend-git.git
cd hoppscotch-backend-git

If you already cloned without submodules:

git submodule update --init --recursive

Install and run:

bun install
bun run prepare:webapp   # extracts official selfhost-web UI + points it at this backend
export GIT_REPO_PATH=./.data/workspace-git   # clone of the shared workspace repo
bun run start

On first start, JWT / webapp signing secrets are generated under the state directory (secrets.json). Optional env overrides still work for tests and special setups.

Type-check and test:

bun run typecheck
bun test

Configuration

Variable Required Description
GIT_REPO_PATH yes Local checkout of the shared Git repo storing collections/ and environments/
HOPP_STATE_DIR no Local state root for meta.json, secrets.json, signing.key (see defaults above)
META_PATH no Override path for users / PATs (default $HOPP_STATE_DIR/meta.json)
JWT_SECRET no Override JWT/PAT pepper (default: auto-generated in $HOPP_STATE_DIR/secrets.json)
PORT no Listen port (default 3200)
GIT_AUTO_PUSH no true to git push after each commit (default false)
WEBAPP_FRONTEND_PATH no Frontend files bundled for Hoppscotch Desktop (default ./webapp-frontend)
WEBAPP_SERVER_SIGNING_SECRET no Override ed25519 seed for desktop bundle signatures (default: auto-generated in secrets.json)
WEBAPP_SERVER_SIGNING_KEY_FILE no Override signing key path (default $HOPP_STATE_DIR/signing.key)
DEV_USER_OVERRIDE no Dev-only JSON { "email", "displayName", "uid"? } to override local identity (ignored/rejected in compiled builds)

Each user runs their own server. Authentication is the local macOS account via dscl (RecordName, EMailAddress, RealName), unless DEV_USER_OVERRIDE is set. Hoppscotch-compatible /v1/auth/* routes remain as stubs (empty providers, desktop token exchange).

Git workspace layout

$GIT_REPO_PATH/
  collections/<id>.json    # Hoppscotch HoppCollection (v12)
  environments/<id>.json   # Hoppscotch Environment (v2)

Useful endpoints

  • GET /health
  • Desktop instance: GET /api/v1/key, /api/v1/manifest, /api/v1/bundle
  • REST CRUD: /v1/collections, /v1/environments
  • CLI: GET /v1/access-tokens/collection/:id, GET /v1/access-tokens/environment/:id (Bearer pat-…)
  • Auth: /v1/auth/providers, /signin, /verify, /refresh, /logout, /verify-token
  • GraphQL: POST /graphql (personal workspace ops + subscriptions)

Example CLI run against a local server:

hopp test <collection-id> --token pat-… --server http://127.0.0.1:3200

License

This project is licensed under the MIT License, the same as Hoppscotch.

Upstream Hoppscotch code under hoppscotch-upstream/ retains its own MIT license and copyright.