I don't understand the fascination with "single file" libraries. Sure, you can take a well organized tree of a few dozen C files and turn it into a single ten-thousand-line monstrosity, but why on earth would you want to?

Because C has no package system and it sucks, and having a single file (ideally with no dependencies, which isn't the case here) makes it super easy to integrate it anywhere.

A good example of that IMO is cJSON[1], it's a small self-contained single file implementation of a JSON reader and parser. It's easy to use, the code is pretty clean and easy to follow and I never ran into any obvious limitation. I very much recommend it.

There are also projects that are developed as multiple files but amalgamated into a single huge file before release. SQLite does that: https://sqlite.org/amalgamation.html

> Over 100 separate source files are concatenated into a single large files of C-code named "sqlite3.c" and called "the amalgamation". The amalgamation contains everything an application needs to embed SQLite. The amalgamation file is more than 220,000 lines long and over 7.5 megabytes in size (as of 2018-11-24).

> Combining all the code for SQLite into one big file makes SQLite easier to deploy — there is just one file to keep track of. And because all code is in a single translation unit, compilers can do better inter-procedure optimization resulting in machine code that is between 5% and 10% faster.

[1] https://github.com/DaveGamble/cJSON

Tossing everything into a single file is not required.

You can use includes to have "a single file to add to the project", and still split your code in smaller, readable files.

See https://github.com/jedisct1/libhydrogen for example. It's a single-file crypto library from an application perspective, but everything was not stored into a single, hard-to-navigate file.