[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)