Back to Blog
curl Is Great. The Mess Around It Isn't.
N

Nikolas Dimitroulakis

07/07/2026

curl Is Great. The Mess Around It Isn't.

curl is a brilliant execution tool. But real API work is auth, environments, chains, docs, and Git, and that's where "just use curl" quietly stops being true.

As a team, we've been working with APIs at ApyHub for years, and we went through pretty much every tool along the way. Postman, back when it was still a Chrome extension. Insomnia. The obvious ones. Some we liked, some we quietly abandoned, some we have opinions about that don't fit in this post (most of those ended up on our comparison page instead).

But today I want to talk about a different tool. One we think is actually great. One we still use. curl.

I use curl. Most developers I know use curl. It has been running the internet since 1998, it's on every machine you'll ever SSH into, and it does exactly what it says with zero ceremony. Nothing in this post argues otherwise.

Here's the thing though. Whenever Voiden comes up somewhere, the most common pushback is some version of "just use curl." And there are two very different claims hiding inside that sentence.

"You can call an API with curl." True. Obviously true.

"curl is enough as an API working environment." That's a much bigger claim. And for most teams it stops being true surprisingly fast.

curl is a low-level HTTP execution tool. Voiden is a workspace for API work: writing requests, organizing them, reusing pieces, documenting them, testing them, versioning them in Git. Different jobs. So this isn't "curl vs Voiden." It's about the gap between those two claims.

What "just curl" actually turns into

Real API work is almost never one request typed into a terminal like some beautifully minimalist Unix haiku.

It starts that way. Then it turns into auth. Then environments. Then copied headers. Then reused payload fragments. Then request chains, where request three needs a token from request one. Then documentation, because a teammate asked how the thing works. Then testing. Then debugging a response from last Tuesday. Then sharing a working example in Slack. Then reviewing a change in a PR. Then trying very hard not to break prod because you forgot to swap one token or one base URL.

At that point nobody is using "just curl" anymore. They're using curl plus shell scripts, plus a notes file, plus .env files, plus commands copied out of old Slack threads, plus a couple of random JSON files, plus tribal knowledge that lives in one senior engineer's head. We know because we did exactly this for a long time.

Which is fine. Genuinely. Right up until it isn't.

The problem with that stack isn't aesthetics, it's that the glue is invisible and fragile. A shell script with six curl calls and inline tokens doesn't produce a readable diff, so "what changed in our auth flow last month" has no good answer. The working command lives wherever it was last pasted, so onboarding a new teammate is archaeology. And which token goes with which base URL for which environment lives entirely in your head, which is how you end up debugging prod with a staging payload. Or the other way around, which is worse.

Also: the same auth header, copied 45 times across scripts and snippets, like a person slowly losing control of their life. Rotate the token once. Now go find all 45.

None of this is curl's fault. curl did its job perfectly every single time. The gap isn't in curl. It's in everything around it.

Where Voiden fits

Voiden doesn't replace curl's job. It replaces the shell scripts, the notes file, the Slack archaeology, and the tribal knowledge.

Everything is a plain-text .void file: a Markdown document that holds the request, its docs, and its tests together, stored in your repo like any other file. A request looks like this:

---
type: request
content:
  - type: method
    content: GET
  - type: url
    content: https://echo.apyhub.com
---

Around that sit the workspace parts curl was never supposed to handle. Auth, headers, params, and bodies are independent blocks that can be added, reused, overridden, and stitched together, so your OAuth setup exists once, not 45 times. Environments are profiles you switch, not a memory test. The docs live in the same file as the executable request, so they can't drift into fiction the way a separate wiki page does. And because it's all plain text in Git, a change to your auth flow shows up as a readable diff in a PR: "Added OAuth block, updated base URL, fixed the login endpoint."

For the longer stuff, you can stack multiple requests in one file, or point the Stitch runner at a set of .void files and run the whole sequence with pass/fail reporting, instead of maintaining a bash loop you're afraid to touch.

The files are plain Markdown, so they're readable in any editor, with or without Voiden installed. No proprietary format, no account, no cloud dependency. If you leave, your files still make sense.

There's a short video showing the block model if you'd rather watch than read: meet Voiden Blocks.

curl stays in the workflow

This is the part the "curl vs Voiden" framing misses.

Voiden's request history can replay any request as a cURL command. The moment you need to hand something to a CI job, a coworker over SSH, or a bug report, you're one step from a portable one-liner. curl is the universal exchange format for HTTP, and that's exactly the role it's brilliant at.

And to be fair in the other direction: for a genuine one-off request, curl wins, full stop. Voiden is a desktop app. curl is a single command that's already on your machine. If your API work truly is one request, once, you don't need a workspace and you shouldn't install one.

But if your terminal history is doing the job of a repository, your notes app is doing the job of documentation, and Slack is doing the job of version control, then the honest answer to "just use curl" is: you already stopped. You just didn't pick what replaced it.

Getting Started

  1. Download Voiden and open it in the repo where your API code already lives.
  2. Create one .void file for a request you currently keep as a curl command in a notes file.
  3. Pull the auth into a reusable block, add a one-line doc, and commit it to Git.

And if you're sitting on years of saved Postman collections, they import too, so nothing gets left behind.

That's the whole migration. One command at a time, whenever a curl one-liner graduates into something a teammate needs too.

Download Voiden at voiden.md/download, dig through the source at github.com/VoidenHQ/voiden, or start with the docs at docs.voiden.md. And if you disagree with all of this and remain team "just curl," tell us why in GitHub Discussions. We do, after all, use curl too.

Related Posts