Your .http tests,
without the JVM.

httpsuite runs the .http files you already author in GoLand or VS Code — pre-request scripts, response handlers, client.test assertions and all — as tests in CI. Plain text in your repo, run with no JDK to install and no JVM to babysit.

JetBrains HTTP Client compatible — verified conformant against its own ijhttp
ci — httpsuite — 80×24
$ httpsuite ./api

PASS  POST  https://api.example.com/login     200  89ms
    logs in and captures the token
PASS  GET   https://api.example.com/profile   200  12ms
    returns the created user
    name matches

2 requests  2 passed  0 failed  101ms
The case for .http

API tests belong in your repo.

The requests you use to build and debug an API are worth keeping — but too often they live in a GUI or a cloud workspace, drifting out of sync with the code they test. .http files put them back where they belong: plain text, versioned in git, reviewed in pull requests. httpsuite runs those same files in CI — the identical scripts and assertions you ran in your IDE — with nothing to install: no JDK, no Node, no runtime to provision, patch, and wait on.

What it does

Executes your requests and their pre-request / response-handler JavaScript, evaluates client.test and declarative # @expect checks, propagates variables across requests, and reports pass/fail for a terminal or CI.

What it doesn't need

No JVM to provision, no runtime to keep patched, no daemon. It runs wherever your CI already does — macOS, Windows, and any Linux, down to Alpine/musl, distroless, and FROM scratch images.

Features

Everything the runner needs. Nothing it doesn't.

No JVM to babysit

Nothing to install, provision, or keep patched. Where ijhttp needs a JDK 25 in every image, httpsuite is one small binary that drops into distroless or scratch unchanged.

JetBrains-compatible scripting

Pre-request < {% %} and response > {% %} handlers, client.test, client.global, the response DOM, and jsonPath — executed by the pure-Go goja engine (ES2015+).

Verified against ijhttp

A conformance harness runs the same .http files through httpsuite and JetBrains' own CLI, then diffs their JUnit reports test-by-test. On the shared API, they agree.

Declarative assertions

Don't want to write JavaScript? Attach # @expect status == 201 comments. Status, headers, JSON body paths, types, dates, and duration — no scripting required.

Suite orchestration

An httpsuite.yaml groups files (parallel or serial, per-group timeouts), runs data-driven rows from inline tables, JSON or CSV, retries a request until it passes, and shares one logged-in session across a group's setup: and files. Or just point it at a directory.

CI-native output

Coloured and aligned on a terminal, plain and diffable with no TTY, and JUnit XML via --report for your CI dashboard. Exit 0 pass, 1 fail, 2 setup error.

Your JetBrains environments

Reads the same http-client.env.json and .private.env.json files GoLand uses — $shared and private overrides included — with --env prod. No re-keying config for CI.

A superset of the format

Everything the JetBrains client parses, plus things stock ijhttp won't: block comments, folded and spread headers, in-place response references, and lazy @var := declarations. Files stay portable.

Variables & chaining

Dynamic {{$uuid}}/{{$timestamp}}, eager and lazy vars, a shared cookie jar, and in-place chaining like {{login.response.body.$.token}} — carry auth and IDs across requests without a line of script.

How it works

From GoLand to green pipeline in three steps.

01

Install

A single binary via Homebrew or go install. Released binaries need no toolchain.

brew install uradical/tap/httpsuite
# or
go install github.com/uradical/httpsuite@latest
02

Point it at your .http files

The same files you author and debug in the IDE. Add > {% client.test(...) %} handlers, or attach declarative # @expect checks — whichever you prefer.

GET {{base}}/users/{{id}}

> {%
  client.test("returns the user", () => {
    client.assert(response.status === 200);
    client.assert(response.body.name === "Ada");
  });
%}
03

Run it in CI

Point httpsuite at a file or directory. It exits non-zero on any failure and writes a JUnit report for your dashboard — no JDK, no Docker image with a runtime baked in.

httpsuite --report report.xml ./api
Before & after

Same file in the IDE and the pipeline.

The request and its response-handler test are authored once in GoLand. httpsuite runs the identical file in CI — and a conformance harness proves it agrees with JetBrains' own ijhttp, test by test.

Authored in GoLand login.http
@base = https://api.example.com

POST {{base}}/login
Content-Type: application/json

{ "user": "ada", "pass": "..." }

> {%
  client.test("logs in", () => {
    client.assert(response.status === 200);
    client.global.set("token", response.body.token);
  });
%}
httpsuite in CI $ — exit 0
$ httpsuite --report report.xml ./api

PASS  POST  .../login    200   89ms
    logs in
PASS  GET   .../profile  200   12ms
    returns the created user

# report.xml → JUnit for your CI dashboard
# conformance harness vs ijhttp: CONFORMANT
Install

No JDK required.

Static binaries for macOS, Linux, and Windows. From source needs Go 1.26+; released binaries need nothing. MIT licensed.

Actively developed. Flags and conventions may still change.

brew install uradical/tap/httpsuite

httpsuite ./api

Until v1.0: the Homebrew tap may not be published yet. Install with Go, or build from source:

go install github.com/uradical/httpsuite@latest
# or
git clone https://github.com/uradical/httpsuite
cd httpsuite && go build .

Documentation  ·  Conformance harness  ·  Source code