CLI tool
Orange-OpenSource/hurl avatar
Orange-OpenSource/hurl

Hurl: HTTP Tests in Plain Text, Run from a Single Binary

Hurl, run and test HTTP requests with plain text.

19,230 stars748 forksRustApache-2.0

At a glance

What is it?
Hurl is a Rust command line tool that runs HTTP requests written in a plain text format and asserts on the responses. It suits engineers who want API checks in version control without a GUI client.
Who is it for?
Adopt Hurl if your API checks belong in the repository next to the code and you want them runnable from a shell, a container or CI without a GUI client. Do not adopt it if you need a graphical request builder, or if your tests depend on logic that a text format cannot express.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Hurl Replaces and Who It Is For

Hurl is a command line tool that runs HTTP requests defined in a simple plain text format, and it can also evaluate queries on headers and body responses. The README frames it as versatile: usable for fetching data and for testing HTTP sessions. That dual role is the point. The same file that performs a login can assert that the login returned a 302 and captured a CSRF token for the next request.

The audience is narrow but real. If your API tests live in a GUI client and cannot be reviewed in a pull request, Hurl moves them into .hurl files that sit beside the code. If your tests live in a scripting language, Hurl removes the runtime: the README describes a single binary with no runtime required, written in Rust and powered by libcurl. The project is published by Orange Open Source under Apache-2.0, and the README states it is adapted for REST and JSON APIs, HTML content, GraphQL and SOAP. That list matters because most HTTP test tools pick one of those and treat the rest as strings.

How a .hurl File Executes: Requests, Captures, Asserts

A .hurl file is a sequence of entries. Each entry starts with a method and a URL, optionally followed by headers and a body, then a response line such as HTTP 200, then sections. The README shows [Captures] with an XPath query pulling a token out of an HTML meta tag, and [Asserts] with jsonpath, xpath, header and status checks. Values captured in one entry are referenced later with double braces, so the login example posts token: {{csrf_token}} into the next request.

The data flow is linear and file-scoped. Requests run in the order written, captures become variables, and assertions run against the response. The chaining example in the README is four consecutive GET lines with no assertions at all, which is the fetching use case: Hurl behaves like a scripted curl. On the testing side, the README shows predicates such as jsonpath "$.tests" count == 25, a regex match on an id, a duration check in milliseconds, and a sha256 comparison against response bytes. GraphQL bodies are written inside a fenced graphql block in the file, and SOAP requests are just XML bodies with headers.

The engine is libcurl. That is a design decision with consequences: HTTP/3, IPv6 and proxy handling come from curl rather than from a reimplementation, and the README claims the tool is fast and efficient on that basis. It also means Hurl inherits curl's model of the world, including its certificate and proxy semantics.

Installing Hurl and Running a First Captured Login

The README points to the documentation site at hurl.dev as the resource for installation, and the repository ships a packages/ directory and a completions/ directory, which is where distribution artifacts and shell completions live. Because the README itself does not print an install command, treat the documentation as the source of truth for your platform rather than copying a command from a blog post.

Once the binary is on your PATH, write a file named login.hurl. The README gives this example almost verbatim, and it is the pattern worth learning first because capture-and-reuse is what separates Hurl from a curl wrapper:

hurl
# Go home and capture token
GET https://example.org
HTTP 200
[Captures]
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"

# Do login!
POST https://example.org/login
[Form]
user: toto
password: 1234
token: {{csrf_token}}
HTTP 302

Run it with hurl login.hurl. If the first response lacks the meta tag, the capture fails before the login is attempted, which is the behaviour you want: the failure points at the page that changed. The README also documents a verbose mode and an error format under Debug Tips, plus export of the equivalent curl commands, which is useful when you need to hand a failing request to someone who does not have Hurl installed.

Where Hurl Is the Wrong Tool

Hurl is a text format, and that is a hard boundary. If your test needs to compute a signature over a request body, branch on a value, or loop until a condition holds, the format has to express it or the test does not exist. The README's table of contents lists polling and retry, delaying requests and skipping requests, so some control flow is present, but the documentation does not describe general programming constructs. Do not choose Hurl expecting to write arbitrary logic in the test file.

Second, the tool is a CLI. Teams that need a GUI request builder, a shared workspace with saved environments, or non-engineers authoring requests will find the plain text format a barrier rather than a feature. The README explicitly positions the text format for devops and developers, which is a statement about who is expected to edit these files.

Third, assertion breadth is bounded by the query types the tool implements. The README demonstrates XPath, JSONPath, header, status, duration and sha256 checks. If your contract testing needs schema validation or semantic diffing beyond those, Hurl is a runner, not a contract framework. Finally, the README does not document rollback or version pinning behaviour for the binary itself, so treat upgrade policy as something you decide rather than something the tool enforces.

Hurl Compared with Postman and with curl

Against Postman, the difference is where the test lives and what runs it. Hurl files are plain text in your repository, executed by a single binary from a shell or CI job. Postman collections are authored in a GUI and executed by a runner, which is friendlier for exploratory work and for people who do not want to read a diff. The README's own framing supports this split: it lists Text Format and Fast CLI as reasons to choose Hurl, and the search phrases people use around the project include Hurl vs Postman and Hurl postman, so the comparison is one users actually make. If your review process is pull requests, Hurl fits. If your process is a shared workspace, it does not.

Against curl, the difference is assertions and chaining. Hurl uses libcurl under the hood, and the README describes it as adding syntactic sugar to run and test HTTP requests while staying the curl we love. A curl command fetches; it does not fail a build because a JSON field changed type. Hurl adds the response line, the [Asserts] section and the [Captures] section on top of the same engine. The README documents exporting curl commands, which is a quiet admission that the two are meant to interoperate rather than compete: you prototype in curl, then encode the check in Hurl.

Reports, CI Wiring and the Apache-2.0 Licence

The README states Hurl is easy to integrate in CI/CD, with text, JUnit, TAP and HTML reports, and the table of contents lists HTML, JSON, JUnit and TAP report formats plus a JSON output mode. JUnit and TAP are the two that matter for most pipelines, because CI systems already parse them and surface failures per test case. The HTML report is the one you open locally when a run fails and you want to see the request waterfall.

Upgrade cost is the part the README understates. Hurl ships as a single binary, so upgrading means replacing a file or pulling a new image; there is no runtime to patch. But the format itself evolves, and the jump from 7.1.0 in November 2025 to 8.0.0 in April 2026 is a major version, which by convention signals breaking changes. The CHANGELOG.md at the repository root is where those changes are recorded, and reading it before moving a suite from 7.x to 8.x is cheaper than debugging a capture that silently stopped matching.

Licensing is Apache-2.0, a permissive licence that permits commercial use, modification and redistribution provided the licence text and notices are preserved. The repository has a LICENSE file and the README links to it under Resources. This is a summary of the identifier, not legal advice; if you redistribute the binary inside a product, have your own counsel read the actual terms.

Editorial conclusion

Adopt Hurl if your API checks belong in the repository next to the code and you want them runnable from a shell, a container or CI without a GUI client. Do not adopt it if you need a graphical request builder, or if your tests depend on logic that a text format cannot express. Before committing, get the binary from the documented source, confirm the version it reports, and execute one .hurl file that captures a token and reuses it, since that is the pattern most suites depend on.

Frequently asked questions

What is Hurl used for?

Hurl is a command line tool that runs HTTP requests defined in a plain text format, and it can evaluate queries on response headers and bodies. The README describes it as usable both for fetching data and for testing HTTP sessions, including REST, SOAP, GraphQL, HTML and other XML or JSON based APIs.

How do I install the Hurl CLI?

The README points to the documentation at hurl.dev as the resource for getting the tool, and the repository contains a packages/ directory where distribution artifacts live. The README does not print an install command itself, so follow the documentation for your platform.

Can Hurl pass a value from one request to the next?

Yes. A [Captures] section stores a value extracted with a query such as xpath, and later requests reference it with double braces, for example token: {{csrf_token}}. The README's login example captures a CSRF token from an HTML meta tag and posts it back on the next request.

Does Hurl work in CI pipelines?

The README states Hurl is easy to integrate in CI/CD, with text, JUnit, TAP and HTML reports, and the table of contents also lists a JSON report and a JSON output mode. JUnit and TAP are the formats most CI systems already parse.

Official sources

  1. License: Apache-2.0
  2. Orange-OpenSource/hurl on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/orange-opensource-hurl.svg)](https://hysenlabs.com/projects/orange-opensource-hurl)