I recently rewrote this site's source code to a simpler language, and wrote my own static generator for the new source.
I did this to get rid of the site generator I'd previously used, Hugo. I had wanted to get rid of it for some time—and even came close to it in early 2025—but that the project has begun integrating code generated by language models is what pushed me to act. The last thing I need in a site generator is the kind of unreliability introduced by that nonsense.
Still, this process gave me the opportunity to think about why I'd wanted to step away from Hugo for so long. I very much disliked the program, only using it because it let me write this site from the comfort of a plain text editor without needing to roll my own HTML—automatic headers and footers are a necessity for any site and I simply can't tolerate needing to update these manually in every single one of the site's pages when I inevitably want to make this kind of change. That Hugo enabled this was just about the only point in its favour, because the program is otherwise way too featureful for my taste.
Hugo supports templates, shortcodes, layouts, modules, menus, archetypes, and so much more. Like, a lot more. I'm not even sure what the difference between a template and a layout is in the first place. The program's help documentation doesn't make the difference between these things clear to me, and hours of debugging never clarified the matter either. I simply smashed things together by trial and error until they looked acceptable, then never probed further into inner workings—because it'd so often break my site whenever I'd try to do so.
That a software application has features not well-suited to me is not a big deal. That a software application is packed to the brim with features that I will never touch—either because I have no interest or can't figure them out—is also not inherently a big deal. What I wanted to talk about is the effects of scope creep on software.
Many software projects start small, usually as solutions to problems the author themselves face. They are meant to solve one specific problem really well, or to be an easy-to-use solution of acceptable quality for an entire problem space. This is how all of my own projects start, and usually how they finish. As a developer I simply can't cope with the complexity I create; Some would say that I am a bad engineer, but I would say that discretion is the better part of valor.
Naturally, many of the biggest software projects do not work like this. If they start simple, they don't stay that way. Over time, popular software projects have a tendency to pick up new features demanded by the audience. User-requested features can sometimes be a genuine boon to an application but much more often tend to exist as afterthoughts which were bolted onto a foundation that was not built to accommodate the new functionality. Best case, a project's maintainers will rethink the concept behind a software project with the new functionality in mind and come up with an entirely new solution which covers a larger problem space that includes those issues which later features were meant to address.
The common case is just that projects keep taking on new features.
Every time a maintainer implements a feature which isn't part of an application's original vision, a feature which doesn't neatly fit into what has already been built, it becomes easier to accept the next one. Every time software is made more difficult to use due to the presence of distracting features, all but the most dedicated of power users become less likely to engage with that noise. Feature creep may continue for a long time, but every software developer has an upper limit of code they can handle in one project.
I suspect that this conflict between feature creep and complexity limits is a big driver behind the adoption of vibecoding (generation of code using language models) in free software. Code generators allow maximalist software developers to continue maximizing their software. New features can be shipped faster than ever before. Everyone gets to have their requests fulfilled, all at the cost of software becoming more brittle and broken than ever.
That's not to say that smaller, more minimalistic projects are somehow immune to vibecoding—they aren't. What I'm getting at is that I think there is a straight line between scope creep and vibecoding. The larger a software project is, and the faster it grows, the more likely it'll eventually turn to vibecoding to keep up the pace. It won't work, but it is tempting.
I'm not a fan of feature maximalism. I think that featureful software is bad by default—as in, I'm open to the idea that it's important for some software to be complex but that this should be the exception—and that there is a point where an application becomes too complex for users to be able to use effectively. This is a belief I've held for a long time and is exemplified by such ideas as the UNIX philosophy (the belief that it's better for programs to do only one thing exceptionally well than to try and inevitably fail to do everything). I have for a long time believed that the best way to achieve reliability in software is minimalism, and I think the era of indifference to quality ushered in by vibecoding is exemplary of that.
I think it's unfortunate that so many need to put time and effort into escaping the clutches of apathy, and I can only imagine how much worse it is for those who weren't already dedicated to such things before it became acceptable not to care. Perhaps this is a sign that it is more important than ever that software developers for software developers to care, and to do so in ways that won't lead to the temptation to betray the trust users place in us.