A homelab developer has built a custom static site generator in C to avoid the complexity and restrictions of mainstream tools like Hugo, prioritizing simplicity, direct HTML editing, and zero dependencies.
Static site generators are a staple in the homelab and developer community for their security and performance benefits. They generate static HTML files at build time, eliminating the runtime costs and attack surface of a dynamic CMS like WordPress. However, many popular generators impose specific workflows and dependencies that can feel restrictive. Maurycy's blog recently detailed the creation of a custom static site generator written in a single C source file, under 1000 lines, as a direct response to these frustrations.
The core philosophy is a rejection of the translation layers common in other tools. The author argues that since a website is published exclusively on the web, writing in HTML directly is more straightforward than using Markdown. While Markdown is popular, its specification is loose, and parsers can behave unpredictably with complex formatting or URLs. Converting from Markdown to HTML introduces a fragile translation step; the author points out that many WordPress blogs have broken formatting after server updates, a problem that doesn't exist with raw HTML. For code blocks, which are a common pain point, the author contends that adding a full Markdown parser is overkill when syntax highlighting can be handled by other means.
The configuration of mainstream static site generators is another point of contention. Tools like Hugo use complex configuration files that embed a programming language within a template, often with poor documentation. This makes simple customizations, like removing publication dates from archive pages, a frustrating exercise in debugging cryptic error messages. The author's solution is to use a real programming language—C in this case—for the generator itself, making the tool's behavior transparent and modifiable for both the developer and the user.
The architecture of the custom generator is elegantly simple. Each article is a single HTML file with a metadata block at the top, separated by --- from the content. The metadata includes fields like title, date, and tags. The generator scans a source directory, copies all non-HTML files unchanged, and processes HTML files by parsing the metadata and injecting the content into a template that includes the site's navigation and styles. To aid in writing, the generator interprets a lone . on a line as a paragraph break (</p><p>), a simple shorthand that avoids the verbosity of HTML tags for basic formatting.
A key feature is the manual excerpt generation. Instead of relying on an automated word-count snip, which often cuts poorly, the generator looks for an HTML comment <!-- snip -->. The content before this comment is used as the excerpt for the homepage. If the comment is missing, the tool throws an error, forcing the author to consciously decide where the excerpt should end. This manual control ensures excerpts are both informative and appropriately sized for the homepage layout.
After processing all posts, the generator performs the final assembly tasks: sorting all posts by date in reverse order, generating the homepage with the latest five posts, creating an RSS feed with the latest twenty posts, building an archive page (excluding space photos), and generating individual index pages for each of the 13 tags used on the site.
The entire system is contained in that single C file. There are no configuration files, no external assets, and no domain-specific languages. The only requirement is a working C compiler, a stark contrast to tools like Hugo, which pull in over 100 dependencies. This eliminates dependency management and ensures the build process is fast and self-contained.
Migrating the existing blog of over 100 posts was the most time-consuming part of the project. While the conversion could have been automated, the author chose to manually update each post to refresh the writing. The blog's purpose is to improve writing skills, and older posts from before 2024 were deemed subpar. To maintain continuity, all URLs and RSS feed GUIDs were preserved, ensuring existing links and subscribers wouldn't be disrupted. The result is a highly tailored, maintainable tool that perfectly fits the author's workflow, proving that for specific needs, a bespoke solution can be superior to a general-purpose framework.
For those interested in the source code or the philosophy behind it, the project is detailed on Maurycy's blog.

Comments
Please log in or register to join the discussion