Hoppscotch - complete guide to the open-source API client
What if you could test any API endpoint instantly, without downloading anything, creating an account, or waiting for an application to load? That's exactly what Hoppscotch delivers. In a world where Postman has grown into a 500MB behemoth with subscription fees and mandatory cloud sync, Hoppscotch offers a refreshing alternative: open your browser, visit hoppscotch.io, and start testing APIs immediately.
This guide covers everything from basic REST requests to advanced gRPC testing, self-hosting configurations, and CI/CD integration. Whether you're debugging a local development server or building comprehensive API test suites, you'll find practical examples you can use right away.
What is Hoppscotch?
Hoppscotch (formerly known as Postwoman) is a lightweight, blazingly fast, and fully open-source API client that runs directly in your web browser. Created by Liyas Thomas in 2019 as an alternative to heavy desktop clients like Postman, Hoppscotch quickly gained popularity among developers who value simplicity, speed, and privacy.
Unlike traditional API clients that require downloading and installing desktop applications, Hoppscotch works instantly. Just navigate to hoppscotch.io and you're ready to send your first request. No installation, no configuration, no account required for basic usage. This "instant access" philosophy has attracted over 50,000 GitHub stars and millions of monthly active users.
Hoppscotch supports all popular API protocols: REST, GraphQL, WebSocket, Server-Sent Events (SSE), Socket.IO, and even gRPC. It also offers advanced features like environments, collections, pre-request scripts, automated tests, and cloud synchronization. All of this runs in your browser, leaving no trace on your disk.
The story behind the project
Hoppscotch started in 2019 as an open-source project under the name "Postwoman" - a playful reference to the popular Postman tool. The name symbolized a fresh approach to API testing: lighter, faster, and more accessible.
In 2020, the project underwent a rebranding to "Hoppscotch" to avoid potential legal issues and establish its own unique identity. The new name comes from the children's game "hopscotch," symbolizing jumping between requests with ease and agility.
In 2021, Hoppscotch received venture capital funding and became a proper startup with a team developing the Enterprise version. Despite commercialization, the core product remains open-source under the MIT license, ensuring the community always has access to the full-featured tool.
Why choose Hoppscotch?
Key advantages
- Zero installation - Works in the browser, immediately ready to use
- Lightning fast - Built on Vue 3 with Composition API, minimal bundle size
- Fully open-source - MIT License, you can self-host it
- All protocols - REST, GraphQL, WebSocket, SSE, Socket.IO, gRPC
- Privacy-first - Self-hosting option for sensitive data
- Real-time - WebSocket and SSE with live message preview
- Offline support - PWA works without internet after first load
- Dark theme - Eye-friendly interface that saves battery
Hoppscotch vs Postman vs Insomnia
| Feature | Hoppscotch | Postman | Insomnia |
|---|---|---|---|
| Price | 100% free | Freemium ($14/mo) | Freemium ($5/mo) |
| Open Source | Yes (MIT) | No | Partially |
| Requires installation | No (web) | Yes | Yes |
| Application size | ~0 (web) | ~500MB | ~200MB |
| REST API | ✅ | ✅ | ✅ |
| GraphQL | ✅ | ✅ | ✅ |
| WebSocket | ✅ | ✅ | ✅ |
| gRPC | ✅ | ✅ | ✅ |
| SSE | ✅ | ❌ | ❌ |
| Socket.IO | ✅ | ❌ | ❌ |
| Self-hosting | ✅ | ❌ | ❌ |
| CLI | ✅ | ✅ | ✅ |
| Team sync | ✅ (free) | Paid | Paid |
| Offline mode | ✅ (PWA) | ✅ | ✅ |
Getting started
Method 1: instant access (recommended)
# Open in your browser
https://hoppscotch.io
# Done! You can start testing APIs immediatelyMethod 2: self-hosting with Docker
# Single container
docker run -d \
--name hoppscotch \
-p 3000:3000 \
hoppscotch/hoppscotch:latest
# Or with Docker Compose
git clone https://github.com/hoppscotch/hoppscotch.git
cd hoppscotch
docker-compose up -dMethod 3: CLI (Hoppscotch CLI)
# Install via npm
npm install -g @hoppscotch/cli
# Run tests from a collection
hopp test -e environment.json collection.json
# Export collection from Hoppscotch UI and run locally
hopp test my-api-tests.jsonMethod 4: browser extension
# Hoppscotch Browser Extension enables:
# - Bypassing CORS restrictions
# - Testing local APIs
# - Access to cookies
# Install from Chrome Web Store or Firefox Add-onsREST API testing
Basic GET request
Method: GET
URL: https://jsonplaceholder.typicode.com/posts
Headers:
Accept: application/json
# Response: List of posts in JSON formatPOST request with body
Method: POST
URL: https://api.example.com/users
Headers:
Authorization: Bearer <<authToken>>
Content-Type: application/json
Body (JSON):
{
"firstName": "John",
"lastName": "Smith",
"email": "john@example.com",
"role": "developer"
}
# Response
{
"id": 123,
"firstName": "John",
"lastName": "Smith",
"email": "john@example.com",
"role": "developer",
"createdAt": "2025-01-25T10:30:00Z"
}PUT/PATCH request
Method: PUT
URL: https://api.example.com/users/<<userId>>
Headers:
Authorization: Bearer <<authToken>>
Content-Type: application/json
Body (JSON):
{
"firstName": "John",
"lastName": "Doe",
"role": "senior-developer"
}DELETE request
Method: DELETE
URL: https://api.example.com/users/<<userId>>
Headers:
Authorization: Bearer <<authToken>>
# Response: 204 No ContentQuery parameters
Method: GET
URL: https://api.example.com/products
Query Parameters:
category: electronics
minPrice: 100
maxPrice: 500
sort: price
order: asc
page: 1
limit: 20
# Hoppscotch automatically builds the URL:
# https://api.example.com/products?category=electronics&minPrice=100&maxPrice=500&sort=price&order=asc&page=1&limit=20Different body types
# 1. JSON (most common)
Content-Type: application/json
{
"key": "value"
}
# 2. Form Data
Content-Type: multipart/form-data
name: "John"
file: [select file]
# 3. URL Encoded
Content-Type: application/x-www-form-urlencoded
username=john&password=secret
# 4. Raw Text
Content-Type: text/plain
Plain text content here
# 5. XML
Content-Type: application/xml
<?xml version="1.0"?>
<user>
<name>John</name>
</user>GraphQL
Basic query
# Endpoint: https://api.spacex.land/graphql/
query GetLaunches {
launchesPast(limit: 5) {
mission_name
launch_date_local
rocket {
rocket_name
rocket_type
}
ships {
name
home_port
}
}
}Query with variables
# Query
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts(first: 10) {
edges {
node {
title
createdAt
}
}
}
}
}
# Variables (in Variables tab)
{
"id": "user_123"
}Mutation
# Mutation
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
content
author {
name
}
}
}
# Variables
{
"input": {
"title": "My first post",
"content": "Post content here...",
"authorId": "user_123"
}
}Subscription (real-time)
# Subscription
subscription OnNewMessage {
messageAdded {
id
content
sender {
name
avatar
}
createdAt
}
}
# Hoppscotch automatically establishes WebSocket connection
# and displays incoming messages in real-timeFragments for reusability
# Define a fragment
fragment UserFields on User {
id
name
email
avatar
}
# Use in query
query GetUsers {
activeUsers {
...UserFields
lastActive
}
admins {
...UserFields
permissions
}
}WebSocket testing
Establishing connection
URL: wss://socket.example.com
# Optional protocols
Protocols: graphql-ws, graphql-transport-ws
# After connection, status: ConnectedSending messages
// Subscribe to a channel
{
"type": "subscribe",
"channel": "notifications",
"userId": "user_123"
}
// Send a message
{
"type": "message",
"channel": "chat",
"content": "Hello World!",
"timestamp": "2025-01-25T10:30:00Z"
}
// Ping/Pong to keep connection alive
{
"type": "ping"
}Receiving messages in real-time
# Hoppscotch displays all incoming messages
# with timestamps and JSON formatting
← {"type":"pong","timestamp":1706180000}
← {"type":"message","channel":"chat","content":"Welcome!","from":"server"}
← {"type":"notification","data":{"id":1,"text":"New update available"}}Socket.IO support
URL: https://socket-io-server.example.com
# Hoppscotch supports Socket.IO with automatic:
# - Handshake
# - Reconnection
# - Room support
# - Acknowledgments
# Sending an event
Event: chat:message
Data: {"text": "Hello!", "room": "general"}
# Listening to events
Listen: chat:message, user:joined, user:leftServer-Sent Events (SSE)
SSE connection
URL: https://api.example.com/events/stream
Headers:
Authorization: Bearer <<authToken>>
Accept: text/event-stream
# After connecting, Hoppscotch displays incoming events:
event: message
data: {"type":"update","data":{"id":1,"status":"processing"}}
event: notification
data: {"type":"alert","message":"Task completed"}
event: heartbeat
data: {"timestamp":1706180000}SSE with retry and ID
# Server can send:
id: 12345
event: update
data: {"progress": 75}
retry: 3000
# Hoppscotch automatically:
# - Tracks ID for reconnection
# - Uses retry delay
# - Displays all eventsgRPC testing
gRPC configuration
Server URL: grpc.example.com:443
# Load .proto file or use reflection
Proto File: user_service.proto
# Select service and method
Service: UserService
Method: GetUserUnary call
// Proto definition
service UserService {
rpc GetUser (GetUserRequest) returns (User);
}
message GetUserRequest {
string id = 1;
}
message User {
string id = 1;
string name = 2;
string email = 3;
}// Request
{
"id": "user_123"
}
// Response
{
"id": "user_123",
"name": "John Smith",
"email": "john@example.com"
}Server streaming
service NotificationService {
rpc StreamNotifications (StreamRequest) returns (stream Notification);
}// Request
{
"userId": "user_123"
}
// Streaming responses (displayed in real-time)
← {"id":"1","message":"Welcome!","timestamp":"..."}
← {"id":"2","message":"New feature available","timestamp":"..."}
← {"id":"3","message":"Task completed","timestamp":"..."}Environments
Creating environments
// Development Environment
{
"name": "Development",
"variables": [
{ "key": "baseUrl", "value": "http://localhost:3000/api" },
{ "key": "authToken", "value": "dev-token-12345" },
{ "key": "apiVersion", "value": "v1" },
{ "key": "debugMode", "value": "true" }
]
}
// Staging Environment
{
"name": "Staging",
"variables": [
{ "key": "baseUrl", "value": "https://staging.example.com/api" },
{ "key": "authToken", "value": "staging-token-67890" },
{ "key": "apiVersion", "value": "v1" },
{ "key": "debugMode", "value": "false" }
]
}
// Production Environment
{
"name": "Production",
"variables": [
{ "key": "baseUrl", "value": "https://api.example.com" },
{ "key": "authToken", "value": "prod-token-secret" },
{ "key": "apiVersion", "value": "v2" },
{ "key": "debugMode", "value": "false" }
]
}Using variables
# In URL
URL: <<baseUrl>>/<<apiVersion>>/users
# In Headers
Authorization: Bearer <<authToken>>
# In Body
{
"debug": <<debugMode>>,
"apiEndpoint": "<<baseUrl>>"
}
# Hoppscotch automatically substitutes values
# from the active environmentDynamic variables
# Hoppscotch offers built-in dynamic variables:
<<$timestamp>> # Unix timestamp: 1706180000
<<$isoTimestamp>> # ISO date: 2025-01-25T10:30:00.000Z
<<$randomUUID>> # UUID: f47ac10b-58cc-4372-a567-0e02b2c3d479
<<$randomInt>> # Random integer: 42
<<$randomColor>> # Random color: #a3f2c1
<<$randomAlpha>> # Random string: abcxyz
# Example usage
{
"requestId": "<<$randomUUID>>",
"timestamp": <<$timestamp>>,
"testData": "<<$randomAlpha>>"
}Collections
Organizing requests
My API Collection
├── 📁 Authentication
│ ├── POST Login
│ ├── POST Register
│ ├── POST Refresh Token
│ └── POST Logout
├── 📁 Users
│ ├── GET List Users
│ ├── GET Get User by ID
│ ├── POST Create User
│ ├── PUT Update User
│ └── DELETE Delete User
├── 📁 Products
│ ├── GET List Products
│ ├── GET Get Product
│ ├── GET Search Products
│ ├── POST Create Product
│ └── PUT Update Stock
└── 📁 Orders
├── GET List Orders
├── GET Get Order
├── POST Create Order
└── PUT Update Order StatusExport/Import collections
// hoppscotch-collection.json
{
"v": 2,
"name": "My API Collection",
"folders": [
{
"v": 2,
"name": "Authentication",
"requests": [
{
"v": "3",
"name": "Login",
"method": "POST",
"endpoint": "<<baseUrl>>/auth/login",
"headers": [
{ "key": "Content-Type", "value": "application/json" }
],
"body": {
"contentType": "application/json",
"body": "{\n \"email\": \"user@example.com\",\n \"password\": \"secret\"\n}"
}
}
]
}
]
}Import from Postman
# Hoppscotch supports import from:
# - Postman Collection v2.1
# - Insomnia
# - OpenAPI/Swagger
# - cURL
# - HAR (HTTP Archive)
# Simply drag and drop the file or use Import in the UIPre-request scripts
Generating dynamic data
// Pre-request script for JWT
const timestamp = Date.now();
const payload = btoa(JSON.stringify({
sub: "user_123",
iat: Math.floor(timestamp / 1000),
exp: Math.floor(timestamp / 1000) + 3600
}));
// Set variable
pw.env.set("jwtPayload", payload);
// You can now use <<jwtPayload>> in the requestComputing signatures
// HMAC signature for API
async function generateSignature(secret, message) {
const encoder = new TextEncoder();
const key = await crypto.subtle.importKey(
"raw",
encoder.encode(secret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"]
);
const signature = await crypto.subtle.sign(
"HMAC",
key,
encoder.encode(message)
);
return Array.from(new Uint8Array(signature))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
const timestamp = Date.now().toString();
const signature = await generateSignature(
pw.env.get("apiSecret"),
timestamp + pw.env.get("requestBody")
);
pw.env.set("signature", signature);
pw.env.set("timestamp", timestamp);Request chaining
// First request: Login
// Save token from response
// In the next request, use pre-request script:
const loginResponse = pw.env.get("loginResponse");
if (loginResponse) {
const token = JSON.parse(loginResponse).token;
pw.env.set("authToken", token);
}Tests
Writing tests
// Test script (executes after response)
// Check status code
pw.test("Status is 200", () => {
pw.expect(pw.response.status).toBe(200);
});
// Check response body
pw.test("Response has correct structure", () => {
const body = pw.response.body;
pw.expect(body.users).toBeType("array");
pw.expect(body.users.length).toBeGreaterThan(0);
});
// Check specific field
pw.test("First user has required fields", () => {
const user = pw.response.body.users[0];
pw.expect(user.id).toBeDefined();
pw.expect(user.email).toContain("@");
pw.expect(user.createdAt).toBeDefined();
});
// Check response time
pw.test("Response time is acceptable", () => {
pw.expect(pw.response.time).toBeLessThan(500);
});
// Check headers
pw.test("Content-Type is JSON", () => {
pw.expect(pw.response.headers["content-type"]).toContain("application/json");
});
// Save data to environment
pw.test("Save first user ID", () => {
const userId = pw.response.body.users[0].id;
pw.env.set("firstUserId", userId);
});Running tests with CLI
# Install CLI
npm install -g @hoppscotch/cli
# Run tests
hopp test \
-e environments/production.json \
collections/api-tests.json
# Output
Running collection: API Tests
✓ Authentication
✓ Login (245ms)
✓ Get Profile (123ms)
✓ Users
✓ List Users (189ms)
✓ Create User (312ms)
✓ Update User (156ms)
✗ Products
✓ List Products (98ms)
✗ Create Product (502ms)
- Expected status 201, got 400
Results: 6 passed, 1 failed
Duration: 1625msCI/CD integration
# .github/workflows/api-tests.yml
name: API Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Hoppscotch CLI
run: npm install -g @hoppscotch/cli
- name: Run API tests
run: |
hopp test \
-e tests/environments/ci.json \
tests/collections/api-tests.json
env:
API_BASE_URL: ${{ secrets.API_BASE_URL }}
API_TOKEN: ${{ secrets.API_TOKEN }}Self-hosting
Docker Compose (recommended)
# docker-compose.yml
version: '3.8'
services:
hoppscotch-db:
image: postgres:15
container_name: hoppscotch-db
environment:
POSTGRES_USER: hoppscotch
POSTGRES_PASSWORD: secretpassword
POSTGRES_DB: hoppscotch
volumes:
- hoppscotch-data:/var/lib/postgresql/data
networks:
- hoppscotch-network
hoppscotch-backend:
image: hoppscotch/hoppscotch-backend:latest
container_name: hoppscotch-backend
environment:
DATABASE_URL: postgresql://hoppscotch:secretpassword@hoppscotch-db:5432/hoppscotch
JWT_SECRET: your-super-secret-jwt-key
SESSION_SECRET: your-session-secret
REFRESH_TOKEN_SECRET: your-refresh-secret
VITE_BASE_URL: https://hoppscotch.yourdomain.com
VITE_BACKEND_GQL_URL: https://hoppscotch.yourdomain.com/graphql
VITE_BACKEND_WS_URL: wss://hoppscotch.yourdomain.com/graphql
VITE_BACKEND_API_URL: https://hoppscotch.yourdomain.com/api
depends_on:
- hoppscotch-db
networks:
- hoppscotch-network
hoppscotch-frontend:
image: hoppscotch/hoppscotch-frontend:latest
container_name: hoppscotch-frontend
ports:
- "3000:3000"
environment:
VITE_BASE_URL: https://hoppscotch.yourdomain.com
VITE_BACKEND_GQL_URL: https://hoppscotch.yourdomain.com/graphql
VITE_BACKEND_WS_URL: wss://hoppscotch.yourdomain.com/graphql
VITE_BACKEND_API_URL: https://hoppscotch.yourdomain.com/api
depends_on:
- hoppscotch-backend
networks:
- hoppscotch-network
volumes:
hoppscotch-data:
networks:
hoppscotch-network:Nginx reverse proxy
# /etc/nginx/sites-available/hoppscotch
server {
listen 80;
server_name hoppscotch.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name hoppscotch.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/hoppscotch.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hoppscotch.yourdomain.com/privkey.pem;
# Frontend
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# GraphQL API
location /graphql {
proxy_pass http://localhost:3170/graphql;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
# REST API
location /api {
proxy_pass http://localhost:3170/api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Kubernetes deployment
# hoppscotch-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hoppscotch
labels:
app: hoppscotch
spec:
replicas: 2
selector:
matchLabels:
app: hoppscotch
template:
metadata:
labels:
app: hoppscotch
spec:
containers:
- name: hoppscotch-frontend
image: hoppscotch/hoppscotch-frontend:latest
ports:
- containerPort: 3000
env:
- name: VITE_BASE_URL
valueFrom:
configMapKeyRef:
name: hoppscotch-config
key: base-url
resources:
limits:
memory: "256Mi"
cpu: "250m"
requests:
memory: "128Mi"
cpu: "100m"
---
apiVersion: v1
kind: Service
metadata:
name: hoppscotch-service
spec:
selector:
app: hoppscotch
ports:
- port: 80
targetPort: 3000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hoppscotch-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- hoppscotch.yourdomain.com
secretName: hoppscotch-tls
rules:
- host: hoppscotch.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hoppscotch-service
port:
number: 80Authentication in Hoppscotch
Basic Auth
Authorization Type: Basic Auth
Username: api_user
Password: api_secret
# Hoppscotch automatically generates header:
Authorization: Basic YXBpX3VzZXI6YXBpX3NlY3JldA==Bearer Token
Authorization Type: Bearer Token
Token: <<authToken>>
# Header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...API Key
Authorization Type: API Key
Key: X-API-Key
Value: <<apiKey>>
Add to: Header (or Query Parameter)OAuth 2.0
Authorization Type: OAuth 2.0
# Authorization Code Flow
Grant Type: Authorization Code
Auth URL: https://auth.example.com/authorize
Token URL: https://auth.example.com/token
Client ID: your-client-id
Client Secret: your-client-secret
Redirect URL: https://hoppscotch.io/oauth
Scope: read write profile
# After authorization, Hoppscotch automatically
# fetches and uses the access tokenAWS Signature v4
Authorization Type: AWS Signature v4
Access Key: AKIAIOSFODNN7EXAMPLE
Secret Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Region: eu-central-1
Service: execute-api
# Hoppscotch automatically generates:
# - Authorization header
# - X-Amz-Date
# - X-Amz-Security-Token (if applicable)Browser extension
Installation
# Chrome Web Store
1. Open Chrome Web Store
2. Search for "Hoppscotch Browser Extension"
3. Click "Add to Chrome"
# Firefox Add-ons
1. Open Firefox Add-ons
2. Search for "Hoppscotch"
3. Click "Add to Firefox"Extension capabilities
# 1. Bypassing CORS
Allows testing APIs without CORS issues,
even for servers without proper headers.
# 2. Localhost access
Test local APIs directly from hoppscotch.io:
http://localhost:3000/api/users
# 3. Cookies
Passes browser cookies to requests,
useful for session-based authentication.
# 4. Origin header
Modifies Origin header for cross-origin requests.Extension configuration
// Extension settings
{
"interceptor": {
"enabled": true,
"mode": "browser" // or "proxy"
},
"cors": {
"allowCredentials": true,
"allowedOrigins": ["*"]
},
"localhost": {
"ports": [3000, 3001, 8080, 8000, 5000]
}
}Integrations and tools
OpenAPI/Swagger import
# Hoppscotch can import:
# - OpenAPI 3.0/3.1 (YAML/JSON)
# - Swagger 2.0
# - Postman Collection
# - Insomnia Export
# Automatically creates:
# - Collections with endpoints
# - Environment with variables
# - Request body schemas
# - Authentication configGenerate code
# Hoppscotch generates code for requests in languages:
# - JavaScript (Fetch, Axios, XHR)
# - TypeScript
# - Python (requests, http.client)
# - cURL
# - Go
# - PHP
# - Ruby
# - Java
# - C#
# - Swift
# - Kotlin
# Example generated code (Fetch)// Generated JavaScript/TypeScript code
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Authorization': 'Bearer token123',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'John Smith',
email: 'john@example.com'
})
});
const data = await response.json();
console.log(data);VS Code extension
# Hoppscotch for VS Code
# Allows testing APIs directly from the editor
# Installation
code --install-extension hoppscotch.hoppscotch-vscode
# Usage
# 1. Open Command Palette (Cmd/Ctrl + Shift + P)
# 2. Type "Hoppscotch"
# 3. Select "Open Hoppscotch"Keyboard shortcuts
# Global
Ctrl/Cmd + Enter - Send request
Ctrl/Cmd + S - Save request
Ctrl/Cmd + Shift + S - Save as new
Ctrl/Cmd + K - Search collections
Ctrl/Cmd + / - Toggle documentation
# Editor
Ctrl/Cmd + Space - Autocomplete
Ctrl/Cmd + F - Find
Ctrl/Cmd + D - Duplicate line
Tab - Indent
Shift + Tab - Remove indent
# Navigation
Ctrl/Cmd + 1-9 - Switch between tabs
Ctrl/Cmd + W - Close tab
Ctrl/Cmd + Shift + T - Restore closed tab
# Interface
Ctrl/Cmd + \ - Toggle sidebar
Ctrl/Cmd + , - SettingsPricing
Self-hosted (open source)
| Plan | Price | Features |
|---|---|---|
| Self-hosted | Free | Full functionality, own infrastructure |
Hoppscotch Cloud
| Plan | Price | Features |
|---|---|---|
| Free | $0/mo | Unlimited requests, basic collections |
| Personal | $7/mo | History, more storage |
| Team | $12/user/mo | Shared workspaces, roles |
| Enterprise | Custom | SSO, audit logs, SLA |
What's free?
✅ All protocols (REST, GraphQL, WS, SSE, gRPC)
✅ Environments and Collections
✅ Pre-request scripts and Tests
✅ Browser Extension
✅ CLI
✅ Import/Export
✅ Code Generation
✅ Self-hosting
✅ Unlimited requestsFAQ - frequently asked questions
Is Hoppscotch really free?
Yes, Hoppscotch is 100% free and open-source under the MIT license. You can use it, modify it, and self-host it without any restrictions. Hoppscotch Cloud offers paid plans with additional team features, but the core functionality is always free.
Can I use Hoppscotch offline?
Yes, Hoppscotch is a Progressive Web App (PWA). After the first page load, you can "install" it and use it offline. Of course, the requests themselves require connection to the API, but the interface and saved collections are available offline.
How do I bypass CORS in Hoppscotch?
Install the Hoppscotch Browser Extension for Chrome or Firefox. The extension acts as a proxy and automatically bypasses CORS restrictions. Alternatively, you can self-host Hoppscotch with your own proxy backend.
Can I import collections from Postman?
Yes, Hoppscotch supports importing Postman v2.1 collections. Export your collection from Postman as JSON and import it in Hoppscotch through the Import menu. Most features will transfer over, though some advanced scripts may need adjustments.
How secure are my data in Hoppscotch?
For maximum security, use the self-hosted version - then all data stays on your infrastructure. In the cloud version, data is encrypted at rest and in transit. Hoppscotch never stores sensitive data like tokens in plain text.
Does Hoppscotch support GraphQL subscriptions?
Yes, Hoppscotch fully supports GraphQL subscriptions via WebSocket. Just select the "Subscription" type in GraphQL mode and Hoppscotch will automatically establish a WebSocket connection and display incoming data in real-time.
How do I share collections with my team?
In Hoppscotch Cloud, you can create Team Workspaces and invite team members. For self-hosted, export the collection as JSON and share it via Git or any file sharing system.
Can I use system environment variables in CLI?
Yes, Hoppscotch CLI supports environment variables. You can use the --env flag or define variables in a JSON file that can reference process.env:
{
"baseUrl": "${API_URL}",
"token": "${API_TOKEN}"
}Summary
Hoppscotch is the ideal tool for developers seeking a lightweight, fast, and free API client. It works in the browser without installation, supports all popular protocols (REST, GraphQL, WebSocket, SSE, gRPC), and offers advanced features like environments, collections, tests, and pre-request scripts.
Main advantages of Hoppscotch:
- Instant access - works immediately in the browser
- 100% open-source - MIT License, full transparency
- Self-hosting - complete control over your data
- All protocols - REST, GraphQL, WS, SSE, gRPC
- Zero cost - free forever for individual users
Whether for quick API testing during development or full-fledged automated tests in CI/CD pipelines, Hoppscotch delivers everything you need without the bloat of traditional desktop clients.