Skip to content(if available)orjump to list(if available)

Why is this site built with C

Why is this site built with C

129 comments

·March 30, 2025

kianN

One of the most commonly cited drawbacks about C (limited standard library and package management) is something I’ve grown to enjoy when working in a well-loved C codebase.

Instead of learning and working with bloated tool chains, every tool in the repo has been built or added carefully for the task at hand. Simplicity provides a lot benefits over time.

FiniteIntegral

Even though I love 3rd party tools (SDL my beloved) I still find novel uses in the C library. Especially for string-related problems people say "just do it from first principles". Sometimes snprintf is enough for my debugging!

01HNNWZ0MV43FF

I don't usually have tools in my repo, I only have my own code

dezgeg

autotools would like a word with you

kianN

Haha I definitely greatly benefit from autotools infrastructure to such a degree that I took it for granted in my above comment.

klysm

C toolchains are the most painful to set up in my experience and have incredible bloat. Familiarity is not simplicity

dig1

Maybe I'm missing something, but what is painful to set up with C toolchains? On almost every *nix, (g)cc, vi(m) and make are enough to be dangerously productive. Sure, you can overcomplicate stuff with modern IDEs and IDE-like tools, but that is out of the realm of the usual C toolchain.

klysm

I’ve never seen a real project that doesn’t use make, cmake, or some other glue on top of gcc/clang. Dependency management is absolute hell as well

dietr1ch

> dangerously productive

As in SIGSEGV dangerous? C is a language so simple that together with the lack of libraries it'll drag you down to problems you were not going to stumble into in most alternatives.

Sure, eventually you'll get your own scars and learn the hard way lessons that will stick and give you better intuition on how things work, but I don't feel there's need to keep using C these days beyond learning and doing specific low level stuff.

perching_aix

> what is painful to set up with C toolchains?

This reads remarkably tongue-in-cheek, especially when combined with the "dangerously productive" remark a bit later, but: navigating the maze that is picking a C runtime, a libc implementation, a compiler or potentially compiler frontend and backend, a linker, a build tool, a dependency manager, and then figuring out the linking, figuring out the dependency management, figuring out the building process, tackling version control crap (setting up submodules) if needed, then rinse repeat for every single project ever. And if you're targeting not just *nix, but also platforms people actually use (Windows), then this gets especially nasty.

Not your project? Well then you get the chance of taking a deep dive into a random assortment of these, taking up however much of your time. Or you'll just try building it and squash errors as they come. Such a great and sane toolchain and workflow.

All of this is of course completely excluding the very real factor of even knowing about these things, since being even slightly confused about this stuff is an immediate ticket to hours of research on various internet forums to even get to know what it is that you don't know - provided you don't just get sick of all this crap and move on to some other toolchain instead, or start the rote reproduction of some random dood's shitty guide, with the usual outcomes.

xigoi

The compilers require a bunch of arcane flags to actually do something useful, so you pretty much need some kind of build system or at least a shell script.

johnklos

You're not wrong, but you're closer to wrong than right. C toolchains are the best of a collection of rather sucky things.

I can compile all sorts of things on my Mac LC III+ with 36 megabytes of memory. Sure, Perl takes nine days, but it works. What other language can actually be used on a machine with such little memory?

klysm

That’s a weird performance measuring stick to use, and I don’t see how it’s related

xigoi

From what I’ve heard, Nim is being successfully used on microcontrollers.

kianN

I’ve never been on a system that doesn’t have either gcc or clang built in.

But disclaimer that my experience in C is limited to a specific subset of scientific computing, so my experience is definitely limited

maccard

Windows, for one.

klysm

gcc/clang isn’t really sufficient though right? Usually there is another build system on top

lelanthran

> C toolchains are the most painful to set up in my experience and have incredible bloat. Familiarity is not simplicity

What are you comparing it to? C++? Java?

checker659

Once you set things up, chances are it'll still build just fine in 5 years tho.

jimbob45

Couldn’t agree more. Vcpkg + CMake doesn’t come close to the convenience of NuGet + MSBuild. The latter Just Works every time. You can’t say the same about C.

theamk

I think Windows is really best served by Microsoft technologies and Microsoft languages. If you want C, there is WSL.

1vuio0pswjnm7

What are the "least painful" toolchains to set up.

How do they compare to GCC in (a) size and (b) portability.

1vuio0pswjnm7

Is python actually a requirement for compiling the rust toolchain so compiling rust toolchain requires compiling python first

https://rustc-dev-guide.rust-lang.org/building/how-to-build-...

inferiorhuman

LLVM is a bit easier to set up in my experience. One of the most irritating things about setting up a GNU toolchain is the hard dependency on texinfo (which has been dropped in later versions I think).

In general I've found rust pretty easy to build.

massysett

I understand all this, no objections at all, I just wonder if the easier thing to do here is to write the blog posts in HTML and drop them in a folder for a web server, the same way I learned to do websites 25 years ago. What's making this complicated is the Markdown and if you want something lightweight, Markdown doesn't pull its weight.

encomiast

It seems like we've spent the past 25 years trying to solve the big headache this creates: you have 100 blog posts, which means 100 html files. Any structural change you need to make to the site involves touching all 100 files. CSS came along and helped separate the presentation from the information a bit, but it still sucked to maintain 100 html files on the server.

mid-kid

I generally just have a makefile that for each page does `cat header.html page.html footer.html > out/page.html`. I realize this can be considered a "static site generator" but I think simple concatenation covers most of the painpoints of writing static sites manually, without introducing intermediate formats and complex processing.

Another option is PHP, which was practically made for the purpose of generating HTML. You can run it on your pages to generate static versions, and just use "include" directives with that.

glandium

Or "server side includes".

thombles

You're right but in my experience the annoyance factor jumps up as soon as you start wanting an RSS feed.

imgabe

I sometimes go down this rabbit hole and wonder why people don't use server-side includes to just have Apache or nginx handle a common header / footer or whatnot. Seems like what they were made for. Are they slow or something?

carlosjobim

They're instant and they work great. PHP includes also.

xnorswap

Isn't this what Jekyll solves?

Posts are all written as markdown, styling and layout are centralised with layout HTML pages and CSS.

I believe indexes can be auto-updated via post metadata.

And it's all static pages once generated, so there's no dynamic load on a database.

lelanthran

Client-side includes are easily done in a custom web component now. I use one. You can write a simple one in about 60 lines of JS.

If all you need is include functionality, then that's the way to go for static file hosting.

jimmaswell

PHP is perfectly sufficient here. Add a static cache if the overhead gets too much.

ryao

There are static site generators. There are even plugins that turn Wordpress and Drupal into static site generators, such that you do not need to edit the files one at a time to make changes.

drwu

I totally agree. Just using a POSIX shell to concatenate header/footer and include the required CSS file, a simple static blog generator can be easily made. (That is what I did with mine.)

No Markdown, no Perl/Python/Ruby, also no binary program, just a few simple shell scripts and plain HTML files.

tiehuis

Using a portable minimal markdown dependency (such as cmark [1]) I think markdown can be quite a low barrier here. I personally do similar to what you have described on my blog, with an additional cmark conversion and find it quite simple [2].

[1] https://github.com/commonmark/cmark

[2] https://github.com/tiehuis/tiehuis.github.io/blob/38b0fd58a2...

rglullis

> Why Is This Site Built with C

Because you are developer who enjoys coding, and you will find any and every excuse to spend more time writing code than you care to admit.

sgarland

If you are a developer who does not enjoy coding, I question your career choice.

indigoabstract

Some developers enjoy coding and some enjoy paychecks. Some enjoy both.

knighthack

Lack of passion and enjoyment for an art form generally correlates with a mentality of doing 'just-enough', rather than a keen desire for craftsmanship.

I think those who enjoy paychecks but don't enjoy coding are likely to be incompetent developers. Which is not a desirable end.

perching_aix

They are probably questioning it too.

But also, enjoying coding recreationally and enjoying coding for work are very different things.

rglullis

[dead]

m000

I think TFA is unfair wrt pandoc's dependencies. I'm not sure if the listed "ecosystem" is what you need to build pandoc from source, or just the result of shitty packaging of pandoc from the OS package maintainers.

For the record, the .deb download from [1] gives you a 146MB statically linked pandoc executable that depends only on libc6 (>= 2.13), libgmp10, zlib1g (>= 1:1.1.4).

[1] https://github.com/jgm/pandoc/releases

zahlman

The "Markdown" package on PyPI gives you a <1MB (including precompiled .pyc; excluding Pip, which is trivial with the know-how) virtual environment that depends only on the Python runtime. Pandoc is massive overkill if you're only interested in converting one format to one other format.

tony-allan

The C program converts Markdown (written by the author) to HTML and is run by the author (and therefore no attack surface). Actual hosting uses GitHub Pages so there is nothing to worry about there. Simple; job done.

"The only work I needed to do was to write a C script (which turned out to be ~250 LOC) to call md4c functions and parse my md files, and then chuck those converted files into the GitHub Pages repo."

zoogeny

> An alternative for saving time with recompilation was to update my script so that only new markdown files or changed ones are marked for recompilation. That would involve too much wizardry if I wanted to make the script nice and robust.

Am I crazy that this doesn't seem like too much wizardry to me? I mean, I have a source directory and a destination directory which gives me a set of unambiguous file to file mappings. At which point I'm looking at comparing some kind of file timestamps. Add in checking if the destination file exists at all and it looks like 2 or 3 system calls and a couple of comparisons.

However, I agree with almost everything else in the article, even just blowing things away and rebuilding every time if it is fast enough. I was musing today that with LLMs we might see a resurgence of personal libraries. Why would I take in a dependency (227 transitive dependencies for that one project dependency!) when I could implement the 20% of functionality from that bloated library that I need? In some circumstances it might be easier to describe the functionality I need to an LLM, review the code and then I have my own vendored implementation.

But if this was me, I would probably choose Go over C. The speed would be good enough, GC for memory safety and convenience, unlikely to be going away in the next 50 years, simple path from static to dynamic generation with standard lib webserver, etc.

bowlofhummus

They're probably already using Git for the website so using a pre-commit hook is by far the easiest way.

miguel_martin

I'm also using MD4C for my website with KaTeX for latex rendering and utterances for comments. Instead of C, I'm generating my site with Nim using Karax + Mummy and publishing to Github Pages with Cloudflare for HTTPS.

Here is the source code (it should be easy to fork for your own site): https://github.com/miguelmartin75/miguelmartin75.github.io

- To generate a page: https://github.com/miguelmartin75/miguelmartin75.github.io/b...

- See usage: https://github.com/miguelmartin75/miguelmartin75.github.io/b...

    - Install nim & run `nimble setup` in repo to install necessary packages

    - Run `nim init` to enable deployment/publishing the site (using git work trees)

    - Serving it locally before deploying is as easy as `nim dev`, see: https://github.com/miguelmartin75/miguelmartin75.github.io/blob/master/config.nims#L15-L16

    - Serving it locally with my private notes (710 files): `nim devpriv`, see: https://github.com/miguelmartin75/miguelmartin75.github.io/blob/master/config.nims#L12-L13

    - Generating the site: `nim gen`

    - To publish the site: `nim publish`
I use Obsidian to write notes and can put top-level YAML metadata on each page and retrieve it in my generator, see: https://github.com/miguelmartin75/miguelmartin75.github.io/b...

For the local development HTTP server (using Mummy), you can refresh the page to regenerate the markdown. Re-generating the page on file changes and refreshing the page with websockets is on my backlog.

Previously I was using GatsbyJS, but have had a lot of trouble with dependencies constantly updating, copying the setup to another computer and generally it was pretty slow to generate the site. Now I can generate my site in <0.1s - even if I include all my private notes (710 markdown files).

assimpleaspossi

We did the same. We created bespoke web sites entirely in C. One of which you may have visited (years ago). And we used C for the same reasons the author mentions and agree with his last paragraph.

Why? At the beginning we were frustrated trying to find one true solution--granted, the perfect solution--to what we wanted to do and how we wanted to work for 20 years. We found that C interfaced with everything, worked everywhere, every programmer knew it, and it could do anything we wanted it to do. If there wasn't a library for something, we could easily make our own.

I could go on and on but I won't. I closed shop just a few years ago cause my reasons for doing that work went away.

null

[deleted]

rorads

I appreciate the dedication to minimal performant code. For me a standard Jekyll setup with a theme and github pages is absolutely fine. It's slow and a bit annoying sometimes but it's very straightforward markdown to html and compiles categories into URL structure. It's also easy to throw in some JS if you need, customise CSS etc.

algo_lover

Still not sure why you chose C though? You could have chosen anything which meets all your requirements.

Many languages have markdown parsers in them, produce binaries, and are portable.

apitman

This is covered in the article.

Brian_K_White

Having read the article, I somehow know why they chose C.

C satisfies all their priorities, and there are not many, or even any other languages that do as well, and none actually better.

gorgoiler

This author is great. Their blog engine really ought to link to the top level. There’s lots of content.

https://marcelofern.com/

I am immediately intrigued about doing code review in Vim (from their posts) as well as using vale.py to lint my prose (from their GitHub.)

jopsen

I'd rather trust 5 libraries written in a memory safe language than one written in C.

Sure, if the memory safe language comes with a package manager that happens to have postinstall hooks, the picture might be different.

But scanning some go packages to see that they don't do I/O is rather feasible.

tuveson

Why? It's a static site generator. He controls the inputs - there's basically no attack surface. I can't think of a situation where lack of memory safety would be less of a problem.

apitman

What type of problem for the author's workflow (rendering markdown files) are you expecting as a result of them using C?

exe34

what's the trust model that you think the author should be using here?