[HN Gopher] Why Is This Site Built with C
       ___________________________________________________________________
        
       Why Is This Site Built with C
        
       Author : todsacerdoti
       Score  : 86 points
       Date   : 2025-03-30 17:51 UTC (5 hours ago)
        
 (HTM) web link (marcelofern.com)
 (TXT) w3m dump (marcelofern.com)
        
       | kianN wrote:
       | 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.
        
         | klysm wrote:
         | C toolchains are the most painful to set up in my experience
         | and have incredible bloat. Familiarity is not simplicity
        
           | kianN wrote:
           | 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
        
             | klysm wrote:
             | gcc/clang isn't really sufficient though right? Usually
             | there is another build system on top
        
               | dmitrygr wrote:
               | I haven't seen a system that has GCC but lacks make
        
               | kianN wrote:
               | I only use clang with a Makefile and I've done some
               | relatively complex projects albeit with only a few
               | collaborators.
        
             | maccard wrote:
             | Windows, for one.
        
           | jimbob45 wrote:
           | 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.
        
           | dig1 wrote:
           | 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 wrote:
             | 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
        
               | immibis wrote:
               | Dependency management in C is the hell that you and your
               | dependency make it, alone. You can try to copy a .a file
               | and a directory of headers into your project, or you can
               | try to make a massive graph of 1000 dependencies that
               | needs a SAT solver to untangle.
               | 
               | Dependencies are hell in JavaScript, Haskell, and Python
               | too, but you don't notice because the computer works
               | through the most common hells automatically... so
               | developers don't hesitate to create hells. In C, they
               | hesitate.
        
             | xigoi wrote:
             | 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.
        
               | dmitrygr wrote:
               | > compilers require a bunch of arcane flags to actually
               | do something useful                  $ gcc lolno.c &&
               | ./a.out        lol, no        $
        
               | pitaj wrote:
               | Now do a project with multiple files.
        
               | Macha wrote:
               | Great, now do TLS, a GUI, graphics rendering or database
               | access.
        
               | gerdesj wrote:
               | I have been a Gentoo Linux aficionado for decades. When
               | you set it up you define a set of CFLAGs and CXXFLAGS
               | etc. Those are your globals, your defaults.
               | 
               | I am also a human. When I deal with another person I have
               | never met before, I have a set of defaults. I override
               | them as required.
               | 
               | gcc (at least) only requires an input and will behave
               | reasonably and generate: a.out.
               | 
               | You might like to pass -O2 for something a bit more
               | complicated. Beyond that then yes you will need to get
               | into details because any engineering discipline is
               | tricksy!
        
           | checker659 wrote:
           | Once you set things up, chances are it'll still build just
           | fine in 5 years tho.
        
           | 1vuio0pswjnm7 wrote:
           | What are the "least painful" toolchains to set up.
           | 
           | How do they compare to GCC in (a) size and (b) portability.
        
         | 01HNNWZ0MV43FF wrote:
         | I don't usually have tools in my repo, I only have my own code
        
         | FiniteIntegral wrote:
         | 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!
        
         | dezgeg wrote:
         | autotools would like a word with you
        
       | algo_lover wrote:
       | 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 wrote:
         | This is covered in the article.
        
       | jopsen wrote:
       | 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.
        
         | apitman wrote:
         | What type of problem for the author's workflow (rendering
         | markdown files) are you expecting as a result of them using C?
        
         | tuveson wrote:
         | 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.
        
         | exe34 wrote:
         | what's the trust model that you think the author should be
         | using here?
        
       | rgovostes wrote:
       | Many tools in the web publishing world are fixated on build
       | speed. I would think transformations of text into templated HTML
       | ought to be basically instantaneous on modern CPUs and SSDs, even
       | for slow interpreters, for websites of even substantial size. It
       | doesn't exactly require algorithms with quadratic runtimes.
        
       | gorgoiler wrote:
       | 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.)
        
       | TrayKnots wrote:
       | Well, I have in essence nothing against this post. I agree with
       | the notion that too many dependencies are not necessary. That we
       | can keep lots of things simpler.
       | 
       | I have nothing against directly implementing this in C or just
       | writing markdown files and have the auto-translated into HTML.
       | 
       | I just don't like his arguments about it must be fast to
       | recompile everything. I am writing this comment, and this is
       | going to take me a few minutes. After all, I am thinking about
       | what I am writing, typing it out, thinking some more. And then,
       | the deploy is the thing that go the author? Really? Time to
       | server is an important metric?
       | 
       | Let's be real, nothing would be lost if it took 5 minutes. He
       | would send it off and 5 minutes later, his phone buzzes,
       | notifying him that it is done.
       | 
       | Alright, he found a way to do it in under 10 seconds. Cool. Good
       | for him. Now that it is built, there is nothing bad about it. I
       | just don't see how this was ever an important KPI.
        
         | skissane wrote:
         | > I just don't like his arguments about it must be fast to
         | recompile everything.
         | 
         | C isn't necessarily fast to recompile everything. Too much
         | preprocessor magic and the compilation can slow down a lot.
         | 
         | And a lot of the reason for that, is that C's preprocessor is
         | inherently weak - e.g. it doesn't explicitly have support for
         | basic stuff like conditionals inside macros - but you can
         | emulate it with deeply nested recursion - which blows up
         | compilation times enormously. If C's preprocessor was a bit
         | stronger and natively had support for conditionals/etc, one
         | wouldn't need these expensive hacks and it would be a lot
         | faster.
         | 
         | Example of real world project where C preprocessor slowed
         | things down a lot is the Linux kernel:
         | https://lwn.net/Articles/983965/
        
           | catgirlinspace wrote:
           | I think the part you quoted is about it needing to be fast to
           | compile from markdown to html, not compiling the C program.
        
         | BlimpSpike wrote:
         | Having the MD file and the website open side by side and being
         | able to see immediate updates as you write is valuable.
        
           | IshKebab wrote:
           | You don't need to actually generate HTML for that though.
           | VSCode will show a markdown preview, and there are tons of
           | other markdown editors that can do that too.
        
         | IshKebab wrote:
         | Yeah I use Pandoc markdown to HTML for my site and it's
         | _easily_ fast enough. Especially if you use a Makefile.
         | 
         | I think this was just a fun challenge rather than to get any
         | kind of useful advantage.
        
       | kuon wrote:
       | I agree with the author that many projects are waaaay to big. I
       | have been using zola and I quite like it. I like the C approach
       | which gives an extra geek point!
        
       | bbkane wrote:
       | I appreciate his argument about tooling lasting a while, but for
       | me the most important thing is the durability of the content
       | format (markdown), and, secondly, owning the domain name.
       | 
       | If, for example, their posts were stored as Word documents or
       | Google Docs, they would have a far fewer options for building and
       | deploying their blog.
       | 
       | But, because theyre're using the (comparatively) simple markdown
       | format, they have a lot more options.
       | 
       | I do something similar and I've migrated my blog from Jekyll +
       | Github Pages to Zola + Netlify without too many issues. If Zola
       | or Netlify go away, I'm confident I can migrate again easily.
        
       | massysett wrote:
       | 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 wrote:
         | 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.
        
           | xnorswap wrote:
           | 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.
        
           | mid-kid wrote:
           | 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.
        
         | drwu wrote:
         | 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.
        
       | rorads wrote:
       | 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.
        
       | m000 wrote:
       | 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
        
       | rglullis wrote:
       | > 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.
        
       | Klonoar wrote:
       | ...am I taking crazy pills or reading this wrong somehow?
       | 
       |  _> I 've been writing about things on a personal website since
       | 2017._
       | 
       |  _> GitHub pages didn 't exist at the time_
       | 
       | GitHub pages existed before 2017. Like, almost a decade before.
        
         | goykasi wrote:
         | I thought the same. He also mentioned hosting on DO and
         | droplets not existing. Im 99.9% sure they existed too. Droplets
         | were literally what they were selling if Im not mistaken. gmail
         | has always been free too (from his archive.org link).
         | 
         | So much of this post feels like alternate history and gloating.
         | Its cool that he wrote a wrapper around an existing library,
         | but his main argument is that C will still be around in "the
         | upcoming decades." Im willing to bet money on Hugo/go existing
         | and still working too -- or any number of other static-site
         | generators.
        
       | zoogeny wrote:
       | > 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 wrote:
         | They're probably already using Git for the website so using a
         | pre-commit hook is by far the easiest way.
        
       | TheRealPomax wrote:
       | Your server is irrelevant. If it's being visited by humans, it
       | just needs to get your information to them in a speedy-enough
       | fashion. It's the content you're serving that matters, not what's
       | serving it. (5MB React bundles? You're bad at the web and you
       | should feel bad. Pure HTML and CSS using brotli compression?
       | You're a superhero)
        
         | immibis wrote:
         | The server technology is relevant because it controls how the
         | information gets to humans. A site without 5MB of Javascript
         | runs faster than one with 5MB of Javascript, all else equal.
         | And Hacker News is a site for technically-minded people who are
         | here to read about things like servers, so even if it was not
         | relevant, it would still be appropriate for Hacker News.
        
       | immibis wrote:
       | I run C on the server. Static content blocks from a directory are
       | converted to #defines by a Python script, so I literally #include
       | "staticpages.inc" and reference them by name. Another Python
       | script generates the code for building the navigation menu
       | (dynamically based on the current page). Another one generates
       | the code to parse the URL and select a request handler. Most
       | pages are header+navbar+content+footer, so I wrote a utility
       | function:
       | 
       | The blog section is a memory-mapped set of C structures, but in
       | the next rewrite I'll directly embed blog posts in the program,
       | too.
       | 
       | I did it this way instead of using a static site generator
       | because I realized that there's no such thing as a static site.
       | My server has to run code to serve any website, including a
       | "static site", so why arbitrarily limit it to the code for
       | loading static files? https://www.immibis.com/blog/12
       | 
       | Not a single library is used, besides libc - at least in the
       | backend code. I use nginx as a reverse proxy and SCGI as the
       | interface from nginx to the C backend.
        
       | assimpleaspossi wrote:
       | 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.
        
       | grandempire wrote:
       | When it comes to personal projects some people love to tinker
       | with new tools, but for me any time not spent writing code is
       | discouraging. Velocity is important for fun and experimentation.
        
       | miguel_martin wrote:
       | 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/b
       | lob/master/config.nims#L15-L16              - Serving it locally
       | with my private notes (710 files): `nim devpriv`, see: https://gi
       | thub.com/miguelmartin75/miguelmartin75.github.io/blob/master/conf
       | ig.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).
        
       | grandempire wrote:
       | This problem would also be solved by the markdown cli tool (or
       | his original pandoc) and make.
       | 
       | Make determines which files changed and their dependencies and
       | reexecutes your script to regenerate the necessary output.
        
       | foul wrote:
       | mhm. I don't understand why a makefile or a redo file is out of
       | the picture.
       | 
       | Yea if you change something in header or footer build speed
       | matters but when the HTML file is done, it's done.
        
       ___________________________________________________________________
       (page generated 2025-03-30 23:00 UTC)