Technical Beauty ■ Episode 8
In 1998, Daniel Stenberg released a command-line tool for transferring data with URLs. Twenty-six years later, it runs on more than ten billion devices. It has never shipped a breaking change. It depends on one external library: libc. The rest of the industry ships breaking changes between minor versions and considers this a feature they call “moving fast.”
curl did not move fast. curl moved correctly.
The Man
Stenberg is a Swedish developer who began the project as
httpget in 1996, a small tool to fetch
currency exchange rates for an IRC bot. It became
urlget. Then, in March 1998, it became
curl.
The name stands for “Client for URLs,” though one
suspects the real reason is that it fits in four characters and
sounds rather good in a shell pipeline.
Stenberg has maintained the project for twenty-eight years. He answers GitHub issues personally. He reviews pull requests. He publishes detailed post-mortems for every security vulnerability. He wrote Everything curl (over 300 pages about a command-line tool) and published it free online. One does not typically write a monograph about one’s own software unless one has rather a lot to say about the decisions behind it. Stenberg has rather a lot to say.
The Numbers
180,000 lines of C. Over 30 protocols (HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, LDAP, MQTT, IMAP, POP3, SMB, SMTP, RTSP, and a dozen more that most developers have never heard of and will one day need at three in the morning). One external dependency. Zero breaking changes in twenty-six years. Code written against libcurl in 2003 still compiles and runs in 2026.
Ten billion installations is not a marketing estimate. Every
Linux distribution ships curl. Every macOS installation includes
it. Every Windows 10 and 11 machine has it. AWS, Azure, and
Google Cloud ship curl in their base images. Every Docker container
that has ever run apt-get has curl. Every HTTP client
library in Python, Ruby, PHP, and Node.js that claims to be its
own implementation is, on closer inspection, a wrapper around
libcurl with a more fashionable API. The number ten billion is
conservative. It may be considerably larger. Nobody can count
accurately because curl is everywhere, in the same way that
oxygen is everywhere, present in quantities that make
measurement feel slightly absurd.
The Dependency
180,000 lines of C is not a small codebase. It is not minimal in
the sense of sed or make. The reduction
is elsewhere. curl has one external dependency: libc. The
C standard library. The interface to the kernel. Everything else
(the protocol parsers, the TLS bindings, the connection
pooling, the cookie engine, the redirect logic, the proxy support,
the authentication mechanisms) is inside the project. Under
one maintainer’s vision. Under one project’s quality
control.
In a world where a JavaScript “Hello World” installs 2,839 packages from a registry that anyone can publish to, the discipline of one dependency is not minimalism. It is a security architecture. Every dependency you do not have is a supply chain attack that cannot reach you, a licence change that cannot break your build, a maintainer burnout that cannot orphan your transitive graph.
Stenberg chose to write 180,000 lines rather than depend on someone else’s 180 packages. The industry considers this approach “not invented here syndrome.” Stenberg considers it “knowing what your software does.” Ten billion devices suggest he may have a point.
The Contract
curl’s deprecation policy is a masterclass in what backwards compatibility actually means when someone means it. Features are not removed. Behaviours are not changed. Flags are not renamed because someone on the team read a blog post about API ergonomics. Code that called libcurl in 2003 still compiles against the 2026 release. Not approximately. Not with a compatibility shim. Not with a migration guide. Exactly.
This is not stubbornness. This is the recognition that software
which runs on ten billion devices cannot afford to break any of
them. Every shell script in every CI pipeline, every PHP backend
calling curl_exec(), every IoT device with a firmware
update mechanism, every embedded system that phones home once a
day: they all depend on curl behaving tomorrow exactly as
it behaved yesterday. Breaking changes are not a product decision.
They are a breach of contract with ten billion counterparties.
The Transparency
Every software project claims to take security seriously. curl demonstrates it. Every CVE (and there have been over 150) receives a public post-mortem. Not a vague advisory. Not a corporate statement reviewed by legal. A technical explanation of what went wrong, how it was discovered, what the fix is, and which versions are affected. Written by the maintainer. Published immediately.
This is not a common practice. Most projects disclose vulnerabilities in the minimum format required by the CVE database and hope nobody reads the diff. Stenberg publishes the diff, the timeline, the root cause analysis, and the commit that introduced the bug. He treats security disclosure as engineering documentation, not damage control. The result is a project with 150+ CVEs and a reputation for being one of the most trustworthy pieces of software on earth. The paradox is not a paradox at all: transparency is the mechanism by which trust is manufactured.
The Book
Stenberg wrote Everything curl. Over three hundred pages. About a command-line tool. Free online. It covers the project’s history, the protocol implementations, the API design, the build system, the release process, and the philosophy that holds the entire edifice together. It is, as far as this author is aware, the most comprehensive documentation ever written for a single Unix utility.
Three hundred pages about a tool whose core usage is
curl URL. That ratio (two words of
interface, three hundred pages of reasoning) is the
signature of software that took the hard problems seriously.
Simple interfaces are not simple to build. They are simple
because someone spent three hundred pages’ worth of
thought ensuring that the complexity stays behind the surface,
where the user never has to see it.
The Layer Beneath
The tool most people know is curl the command. The
tool that actually runs the world is libcurl,
the library. PHP’s curl_* functions are libcurl.
Python’s pycurl is libcurl. Ruby’s
curb is libcurl. When your programming language
advertises its own HTTP client, there is a reasonable chance that
somewhere beneath the abstraction layers, beneath the promises and
the async/await syntax and the ergonomic builder patterns, libcurl
is doing the actual work of speaking to the network.
This is not a criticism of those languages. It is the highest compliment a library can receive: the entire industry uses your code and pretends it wrote its own. libcurl is the session musician of the internet, uncredited on the album, present on every track.
The Discipline
What makes curl technically beautiful is not any single decision. It is the accumulation of correct decisions over twenty-eight years. The decision to depend on nothing. The decision to break nothing. The decision to support every protocol that matters and several that do not yet. The decision to document everything. The decision to disclose everything. The decision, made once and honoured ten thousand times, that the people who depend on your software matter more than your desire to refactor the API.
Stenberg could have rewritten curl in Rust. He could have introduced a v2 API. He could have dropped FTP support because “nobody uses FTP any more”, a claim that is always made by people who have never maintained infrastructure at scale. He did none of these things. He maintained the contract. He added features without removing guarantees. He wrote 180,000 lines of C that ten billion devices trust with their network traffic, and he answered the GitHub issues personally.
The industry calls this “boring technology.” The industry is correct, in the same way that gravity is boring. It is boring because it works. It is boring because it has always worked. It is boring because nobody has to think about it, which is precisely the point.
One dependency. Zero breaking changes. Twenty-eight years. Ten billion devices. The protocol you will need at three in the morning is already compiled in. That is not boring. That is beautiful.