1. 46

    1. 94

      You should write your own SSG ‘cause it’s fun!

      If it’s not fun, don’t do it.

      1. 9

        Probably the most correct answer here :) Thanks for saying it!

      2. -1


    2. 37

      You shouldn’t. What happens is that you implement a minimal feature set to get your website working. Then, next time you want to add something to the website, you realize a necessary feature is missing, and instead of updating the website, you spend your time implementing the feature. This happens over and over again and you lose interest in updating the website because it’s so much work every time.

      1. 40

        Last time I tried, I found that even choosing a static site generator from the seemingly infinite list of options in 2016 was arguably more work than just building one. We tacked on a build pipeline for images and javascript at some point, but other than that I don’t think any features were added during the life of the site. There are certainly features it didn’t have, but that’s just the power of knowing your requirements up front, I guess.

        1. 24

          Not to mention keeping your 3rd party SSG up to date. “Oh, I can’t post to my blog because _____ isn’t compatible with the current version of Ruby/Python/etc. Guess I’ll update it. Oh, now it’s obsoleted some config options I’m using, better learn what the modern equivalent is. Oh, looks like the theme I installed isn’t compatible, is there an updated version? No? Time to look for a new theme. Oh, now I remember I patched the old theme to add a custom feature and my pages won’t render without it; how do I port that patch to the new theme? Wow, looks like the theme engine changed a lot, I don’t recognize half these tags…”

          I’ve been down that road several times.

          1. 7

            The SSG doesn’t interact with the internet or any kind of untrusted data. Hence it’s totally fine to keep a VM or container image with the old working version of the tools forever and never update anything. :)

            1. 12

              An advantage of a statically compiled SSG is you can just keep the binary around forever.

              1. 5

                Sure, but that’s a bit inflexible.

                I’d much rather have the whole compiler environment snapshotted in a container or VM image because then I can make changes to the SSG.

        2. 4

          100% - I tried to get something done and was looking at hugo after a few years and it was quicker to write my own before reading up and making it work.

      2. 14

        I’m not sure it’s fair to make a generalization about this. I found that building my own blog (not actually a SSG) in Rust with Axum and Maud was actually quite comfortable and ergonomic since I was able to lean on the existing tools that exist (Tower for any HTTP stuff, Comrak for markdown parsing etc). It was a fun learning experience, and I think a blog is simple enough to be doable as a learning exercise, but complex enough to expose you to a lot of language features you might otherwise have missed.

      3. 12

        My experience with using an off the shelf SSG is that everything was fine and dandy until I wanted to do something I felt was pretty basic but which I ended up spending hours and hours on trying to get to work before finally giving up. Writing my own would not have this problem. I would just implement the basic features I actually need and then not touch it again.

      4. 8

        This isn’t limited to homemade SSGs though. I’ve had to write quite a bit of Ruby and understand Jekyll internals to get some plugins to work together and in the way I want them to work, and the solutions feel rather hacky and are verbose liquid templates. I’m fairly certain this takes less time than making my own SSG, but from experience it’s much less fun than making it yourself.

        And if you want a feature that’s not yet supported in some SSGs like e.g. Hugo, you’re stuck because there’s no plugin system at all.

      5. 5

        I don’t think this is the case for everyone. I’m sure there are edge cases, but if you simply need your SSG to render posts/pages/RSS you will be fine. The average “simple” blog rarely needs new features.

        1. 4

          Yeah I’ve had my own custom blog site since 2008 and this has never happened to be once. If anything I’ve removed features I realized were unnecessary.

      6. 5

        But it’s fun work. At least for me, as I don’t work in the web world normally. I wrote my own blog engine and over the 24 year history of my blog, there have been features I’ve added (like automatically cross posting to Insta­My­Face­Me­Pin­Tik­Linked­Space­Tot­We­Book­Gram­Trest­In) only to remove later (when the API inevitably change). I’m not worried about the language it’s written in changing too much, as it’s in C.

        In contrast, the rest of my website is a static site, using xsltproc (quite the retro-future approach). I wrote the XSLT back (as far as I can tell) around 2003-2004 and there was only one time I had to update it due to changes in xsltproc. I do not recommend using XSLT—it works, but boy, is it verbose. Way more than Cobol (and it’s a pure functional language, which is even more head exploding).

      7. 3

        What happens is that you implement a minimal feature set to get your website working

        FWIW I did exactly that for https://www.oilshell.org/ . I wrote a shell script that used Gruber’s markdown.pl (packaged in Debian) to put up a single blog post, and then an index.html that linked to it.

        People actually read and liked the blog, which I was slightly surprised by, given that I knew many people had “written off” shell as a language to be learned.

        So now I knew it was worth spending some time on, and gradually added features over the years. The anti-pattern is to “plan” the blog up front.

        Then, next time you want to add something to the website, you realize a necessary feature is missing, and instead of updating the website, you spend your time implementing the feature. This happens over and over again and you lose interest in updating the website because it’s so much work every time.

        That didn’t happen in my case. It’s not too much effort to use shell and Python to add new features.

        It may not look like it, but the site is pretty deep now

        1. I rewrote the TOC generator once (it used to be JS, and is now static) - e.g. the yellow box http://www.oilshell.org/blog/2023/06/narrow-waist.html

        2. I wrote a separate Flask + JS tool to make these little story link boxes, and then I copy and paste into Markdown - http://www.oilshell.org/blog/2023/06/narrow-waist.html#appendix-blog-backlog

        3. I wrote a separate tool in PHP to serve resized images, to save bandwidth - http://www.oilshell.org/blog/2023/06/surrogate-pair.html

        4. I also deleted Google analytics a few years ago, and now use a pipeline of Python + R + JS + shell to make my own graphs. (the thing that is rotting here is the spam detection – there are so many undeclared crawlers these days)

        5. It also has topic tagging, and OpenGraph metadata for Twitter/Mastodon etc.

        I would say that if it were only Python, it would be too much work. I would maybe have given up on doing everything myself.

        I would have fallen into the “programmer blogger trap”. This kind of code can be very repetitive and non-composable in pure Python.

        But gluing everything together with shell makes it feasible. It’s just less code overall. And it’s faster to iterate.

        I mentioned this Unix philosophy / multi-language / multi-process factoring here:


        And to be fair it took me a long time to build up those skills – making a website is not trivial !!! I failed to make websites from scratch before, for sure. Multiple times. The benefit has to be worth the effort, as you say, and the effort is often high.

        But now that I finally have one, I view it as an asset.

      8. 2

        instead of updating the website, you spend your time implementing the feature.

        Except this also happens with SSGs you didn’t write, and then it’s even harder.

    3. 25

      I wrote my own for eatonphil.com, 6 years ago now, because every other SSG kept introducing silly breaking changes over the years that took me a while to debug.

      In contrast mine doesn’t break, and it has not been difficult for me to evolve features slowly over the years.

      1. 8

        This was exactly my experience too. It’s infrequent but over the timespan of years almost guaranteed to happen more regularly than you’d expect, that someone refactors the config format or adds some opaque step that didn’t exist before and it breaks your workflow.


    4. 18

      I have said for a while that you should write an SSG for yourself. It’s very easy in almost every language to open some files, do some light processing and templating, and spit out some HTML. If you write it yourself, you will know how it all works.

      I think as your needs get more advanced, it’s worth looking at the popular SSGs to see if you would benefit from their features.

      What you should not do is to try to compete in the marketplace of SSGs. It is beyond crowded, and all of the advantages of your SSG (simple! does just what you need and nothing else!) come from the fact that you wrote it yourself. No one else is you, so no one else is going to get that advantage.

    5. 11

      When Vercel released Next.js 14 recently, some friends I’ve talked to where still on Next.js 12 and really felt the pressure to upgrade to not fall behind even more.

      /me looks at the code powering my main blog since 2004… still the same Blosxom script…

      1. 4

        I agree, this is a huge sticking point in the whole story. I think this is kind of a forced thing. For a static data, you only need an offline way to regenerate script. Even if you had a script from 2004 - if it still works, it can regenerate stuff when you add a new markdown file.

        The problem here is, will Next.js 12 work in 19 years, like your bloxsom script? Maybe, maybe not. So you go and upgrade, just to be sure.

    6. 8

      I don’t write my own SSG for the same reason that I don’t write my own most other things: ecosystem.

      Jekyll has a load of features that are annoying, but it also has a load of packages that do what I want. I could write my own thing to parse BibTeX and generate nicely formatted publication lists, or I could just use jekyll-scholar and do a little bit of CSS. I could write my own macros to cross-reference FreeBSD man pages, or I could just use jekyll-beastiepress.

      When I want a new feature, I typically find that someone else has already written a Jekyll plugin that does 90% of what I want and can be made to do exactly what I want with a tiny bit of liquid / HTML / CSS. That means that I spend 10% of the effort and can spend the remaining time actually working on content for the site (or on other projects).

      By all means, write a static site generator if you have a special set of requirements, but ‘you should write your own X’ is often bad advice unless the motivation is learning or exploring ideas that are completely different from the mainstream. Writing your own POSIXy OS is a good learning experience, but don’t expect to actually use the result. Writing a not-POSIXy OS might be important if you have requirements where POSIX is a bad fit (i.e. any use case that isn’t running existing POSIX software).

    7. 8

      Follow your instinct and desire to build your own software. I usually read people saying you should use existing software and don’t reinvent the wheel but all the cool software projects are from people reinventing the wheel.

      Fuck it ship it.

    8. 8

      We need more “slow” software that only evolves in a strictly backwards compatible way. You can still typeset a 40-year old document on a current Mac using troff but try fixing a typo on a website made using one of the current SSGs last year. Makes me livid.

      Like the author, I created my own static site generator for some of the small websites I maintain. It has nearly no features, but never let me down in the past ten or so years: https://burningsoda.com/software/tack/

      1. 5

        My blog engine is 24 years old, and while the internals have changed (a lot) over the years, the storage format has not changed in all that time, and the engine from 20 years ago would still work (or at least not crash) on the data today.

    9. 5

      For a personal project this sounds great.

      I worked at a place where someone wrote a site generator that was “special” and they had to spend time supporting it. I replaced it with a SSG and CD. The team that authors the site is much more productive due to there no longer being a developer as a bottleneck. I’ve found the SSG pleasant. The source and templates are usefully arranged with useful hooks and integration points. The authors/users of the site have requested features and they are just plugins. When I have a question about how it works there are reasonable docs and if it comes to it the source isn’t a micky mouse mess. The team also paid for the dev support subscription and now they go ask questions to the dev of the SSG and not me.

    10. 5

      If you can’t reinvent the wheel on your own blog, when can you do it?! I know that this sounds like snark, but it is true. It is one of the few places on the internet where you can actually play and develop your own stuff for the sake of fun and learning. Don’t shy away from doing it.

    11. 5

      I’ve been doing this and having lots of fun with it. I’m using it to learn Zig, and I’m doing everything from scratch, no dependencies. Most recently I implemented basic TeX to MathML rendering. I’m nearly at the point where I can redeploy the site (I used to use Hugo) and then start working on a visual redesign.

    12. 8

      Why You Should Just Write HTML

      1. 6

        OK, I’ll expand.

        Using at least something like staticjinja is not going to hurt you. You can keep using plain HTML and only make use of template inheritance and includes to at least move the unimportant parts of the pages away from the content in a way that makes it easy to come back to them and change things without going through multiple files and repeating the edits.

        I would personally probably also add a way to use Markdown, because I find writing plain HTML tedious and distracting. Good when I need it’s power, bad when I need to &amp;, &quot; and <strong> constantly. I suffer from ADHD, which means that any accidental complexity will make it easier to procrastinate. Also </strong>.

        1. 1

          Using something like staticjinja looks like it’d exactly be a pain. Look at how many fricking breaking changes there’s been in 2 years https://staticjinja.readthedocs.io/en/stable/dev/changelog.html

          You can setup your css so <b> can be synonymous with <strong>

          Yea, typing &amp; is annoying, I suggest typing and instead and using regular quotes than &quot; - maybe there’s some other solution to this that isn’t immediately obvious to me :p

          1. 3

            Using something like staticjinja looks like it’d exactly be a pain. Look at how many fricking breaking changes there’s been in 2 years https://staticjinja.readthedocs.io/en/stable/dev/changelog.html

            Looks like zero? Especially if you just used it from the command line.

            Yea, typing & is annoying, I suggest typing and instead and using regular quotes than &quot; - maybe there’s some other solution to this that isn’t immediately obvious to me :p

            Quoting MDN:

            If you have to display reserved characters such as <, >, &, and “ within the <pre> tag, the characters must be escaped using their respective HTML entity.

            1. 1

              Quotation marks as “…” typographically, as Godzilla intended

        2. 1

          The problem I have with using a form of text markup (like Markup) is properly escaping asterisks when I really want an asterisk (which isn’t often, but does happen from time to time). It’s especially bad when it happens in code I’m posing. Then I have to go back and fix the post. Yes, this happened recently, and it affected the output of the code to render it useless.

      2. 3

        With some way to include navigation and common header, footer, breadcrumbs…

        1. 3

          nav, header, footer. cp template.html todays_post.html. If you need extremely basic templating, template.html.sh > todays_post.html.

          Why do you need breadcrumbs? If we’re talking beyond blogs, you probably shouldn’t write any static site generator and use what exists, because others will need to come along to maintain it…

        2. 1

          Writing raw HTML is also a matter of your editor. If your editor supports snippets and smart expansion, you can write just plain HTML pretty quick. There’s some great vim plugins like emmet.

      3. 1

        I just can’t quit HTML

        I’ve wanted to go to an SSG for years but the simplicity of HTML for such a simple and rarely updated personal site is unmatched. I dealt with Wordpress for a decade more than a decade ago and I’m glad I got away from it because I spent more time upgrading and hardening it than I did blogging on it.

    13. 3

      I did and now I do have a website but there’s no RSS feed and the entries are sorted randomly and not by date. At least I can deploy via git push, but I’m actually kind of missing a WYSIWYG text editor for quick notes. And to create a new page I need to mkdir article_name and add it to a list in a Python script, kind of sucks really.

      1. 3

        WYSIWYG text editor for quick notes

        I am more and more convinced, for playing with tech, go build SSGs. For writing blogs, use Publii or something.

        1. 3

          I agree, the biggest barrier for me when it comes to writing blog posts isn’t the site generation or deployment or formatting, it’s actually typing the words out. And Hugo/Jekyll/… don’t help with that problem.

    14. 3

      I think its valuable to write your own static site generator for a learning experience. I did and I had a lot of fun, it was great.

      But the longer you maintain the software, especially when you start needing other features, you realize how hairy it gets. I did nearly exactly the same setup in Rust as the author, supported it for about a year, and now I’m back on a matured framework (Svelte) specifically.

      There’s just a lot of nuance in static site generation that you don’t really see until you put your head underwater

    15. 3

      Wow - I cannot believe there are so many people commenting on not doing this.

      I agree with the author. I want to have that control and I want to do this.

      1. 4

        I use Jekyll, and I don’t feel that I’ve given up control. What I get for free is:

        • Liquid for writing templates that do processing over collections and so on. Especially for inclusions, so I can have custom headers and footers, table of contents blocks, and so on.
        • Built-in support for pagination, RSS feeds, and so on.
        • SASS for allowing me to structure my CSS with includes, especially composing it with theme-provided CSS.
        • A bunch of off-the-shelf themes that I can customise.
        • Markdown, reST and AsciiDoc support (and other things via plugins, including syntax highlighting for code snippets).
        • Support via a mature plugin for creating publication lists.

        My Cambridge site, for example, is generated with Jekyll, but with a template that I created that matches the departmental style (well, their old style. They replaced it with a hideous one recently). The recent publications list and the publications page are both generated with Jekyll-scholar from the same BibTeX source, which means that adding a new publication just requires pasting the BibTeX from the conference or journal into the file and committing it. I wrote the template that generates the individual bibliography entries and makes the abstract and bibtex collapsible things (no JavaScript now!) but I didn’t have to deal with any of the mechanical work of parsing and processing BibTeX.

        I could do most of this myself but I’d much rather invest the energy writing content and getting the presentation right than in the exact process that’s used to transform my content into a pile of HTML and CSS.

    16. 2

      Be careful with this mindset: you’ll start seeing other places where you’re essentially acting as Chief Integration Engineer rather than actually programming, and start questioning why modern day dev consists of trying to glue together random parts from “experts” who know nothing of your context.

      This is not prescriptive advice, I just detest that modern day dev fixates so much on applying tooling that it becomes profoundly frustrating when you hit an edge case with it.

    17. 1

      I was curious about the lack of file extensions (.html), and I saw you were using Netlify, and that let me to this little feature they’ve got! Pretty neat. https://docs.netlify.com/routing/redirects/redirect-options/#trailing-slash

      The advantage with something like this is that you can have the same URLs whether you use a static site or a server, and if you switch between them, you don’t have to set up redirects.

      Also, I use this same “build your own site from scratch” technique when teaching programming, and this is a step on the path that I feel folx like and return to.

      Thanks for sharing!

    18. 1

      I know what you’re thinking and you’re right, it’s way more work than using something that already exists.

      Before I wrote my own, I used Ikiwiki. I don’t think writing my own was more work than configuring an existing one. It depends of course. I made a custom theme in both cases and you save time if you start from scratch. I also don’t have to deal with updates, saving more time.

    19. 1

      The universe works in strange ways. I was having an itch to implement my own static site generator, despite being fine with Jekyll for many years now. Jekyll doesn’t give me many reasons to complain, and Ruby is my favourite mainstream language.

      I’ve been thinking of using a) BQN or b) Scryer Prolog and revamping my site along with it. BQN is a lot less simple, and hence a much more complete challenge. Markdown parsing is there, but in a website specific script, and there is a simplistic templating engine called barbell. But putting together a structure, finding URLs, and finally, generating templates from arbitrary BQN is gonna be a complete doozy. And it all needs to happen from scratch.

    20. 1

      A static site generator mostly needs to do five things:

      1. Convert markdown to HTML
      2. Render HTML templates
      3. Compile CSS
      4. Generate RSS feeds
      5. Generate a sitemap

      I implemented the first (and part of the second) step of the list completely from scratch, its not perfect but i still use it every day for features such as live reload, syntax highlighted code snippets and macros (and its really fast). It does not yet support markdown tables and deeply nested lists, but im working on that: https://github.com/xNaCly/fleck

      Fleck is the literal german translation of mark.

    21. 1

      There’s a middle way: use an SSG, and modify it to fit your evolving needs.