Hurl
Run and test HTTP requests with a plain text format
Hurl is an open-source command-line tool that runs HTTP requests defined in a simple plain text format. It is used for API testing and can be integrated into self-hosted CI pipelines.
Key features
- Plain text request files
- Built-in assertions
- CI friendly
- Chained requests
Pros & cons
Strengths
- Plain text request files
- CI-friendly and fast
- Built-in assertions
Trade-offs
- No graphical interface
- Curl-style learning curve
Hurl replaces
Last reviewed Aug 26, 2026 · 712 words
This is a complete Hurl test, and it already tells you whether Hurl is for you:
GET https://api.example.com/health
HTTP 200
[Asserts]
jsonpath "$.status" == "ok"
duration < 500
Save it as health.hurl, run hurl --test health.hurl, and the exit code is your verdict. Hurl is a single Rust binary from Orange that runs HTTP requests written in that plain text format, checks the responses against assertions, and chains requests by capturing values from one into the next. There is no GUI and never will be. It replaces the "run the collection" button in Postman with a file that lives in git, diffs cleanly and runs in any CI runner in about a second.
It is curl with a memory and a test harness
Under the hood Hurl drives libcurl, so every option you already know (custom headers, client certificates, proxies, --insecure for a homelab CA) works the same way. What curl lacks is state. A [Captures] block pulls a value out of a response and makes it a variable for later entries in the same file:
POST https://api.example.com/login
{"user": "admin", "password": "{{password}}"}
HTTP 200
[Captures]
token: jsonpath "$.token"
GET https://api.example.com/me
Authorization: Bearer {{token}}
HTTP 200
[Asserts]
jsonpath "$.role" == "admin"
Variables come from --variable password=..., a --variables-file, or environment variables with a HURL_ prefix, so secrets stay out of the file. Assertions cover status, headers, JSONPath, XPath, regex, body hashes and response time, which is more than most people's Postman scripts ever did.
Where a self-hoster actually runs it
Three places earn a .hurl file. First, CI: a tests/ directory in the same repo as the service, executed by Woodpecker or Gitea Actions on a Gitea or Forgejo instance after the container builds. hurl --test --report-junit report.xml tests/*.hurl gives the runner something to render. Second, smoke checks after a deploy: a 10-line file that logs in, creates a record, reads it back and deletes it, run from the deploy script so a broken migration fails loudly instead of at 2 a.m. Third, as a scriptable uptime probe when a plain status check is not enough; a cron job that runs a Hurl file and hits a Healthchecks ping URL on success catches "returns 200 but the JSON is empty" failures that a simple monitor misses.
Retries are built in, so use them for flaky infrastructure
Waiting for a container to come up is the most common reason integration tests fail for boring reasons. Hurl handles it per request:
GET http://localhost:8080/ready
[Options]
retry: 20
retry-interval: 1000
HTTP 200
That retries up to 20 times, a second apart, before failing the entry. Combined with --test and the JUnit or HTML report (--report-html out/), a compose stack can be brought up, exercised and torn down in one CI job with no sleep commands.
What it is not
Hurl is not an exploration tool. When you are poking at an unfamiliar API and want to see headers, tweak a body and try again, a desktop client such as Yaak is faster, and a request you settle on there is easy to transcribe into .hurl once you know what the test should be. It is also not a load tester; it runs entries sequentially and reports timings, but there is no concurrency model. And its learning curve is real for people who never used curl: the format is small, but the header-versus-body-versus-assert rules and the quoting of JSONPath expressions take an afternoon to internalise.
What I'd do
Install the binary from the GitHub releases, write one health.hurl per service you run, and commit them next to the compose files. Wire hurl --test into whatever CI you already have, and run the same files from a nightly cron with a Healthchecks ping. Keep Yaak or a browser for exploring; keep Hurl for anything you want to run twice. For a self-hoster with more than five services, that is a few hours once, and it pays back the first time an update quietly breaks an API you depend on.
Compare Hurl
11 head-to-head comparisons.
Similar developer tools & git apps
Excalidraw
Developer Tools & GitVirtual hand-drawn style whiteboard
Replaces Miro
lazygit
Developer Tools & GitSimple terminal UI for Git commands
Replaces GitKraken, Sourcetree
Hoppscotch
Developer Tools & GitOpen-source API development ecosystem
Replaces Postman, Insomnia
json-server
Developer Tools & GitFull fake REST API from a JSON file in seconds
Replaces Mockoon, Postman Mock
Strapi
Developer Tools & GitLeading open-source headless CMS
Replaces Contentful
NocoDB
Developer Tools & GitOpen-source Airtable alternative
Replaces Airtable