Meandering Soul

This day is done, I'm going home.
eFranes Penguin Avatar

Fountain Update 0x02

28
Feb 2026

I have a thing with announcing a thing then going silent for a year then saying it’s totally happening and then going silent for a year again, haven’t I?

There has been progress though. Irregular, but steady. The current fountain mono-repository gained 104 commits since the last post. Here’s a sneak peek from logs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
2 days ago > feat: Stub fountain commands
2 days ago > doc: Improve build script internal help
7 days ago > build: Add git dependency
8 days ago > fix: Add version requirement
8 days ago > refactor: Extract string reflow to extension
2 weeks ago > feat: Allow for more expressive environment selection
2 weeks ago > fix: Correctly query config
2 weeks ago > refactor: rename
2 weeks ago > style: Prettify
2 weeks ago > chore: Test title extraction

At the moment, I’m still somewhat in the middle of a big refactoring. From the outset, my aim was to keep the project lean and only code whatever is needed to get to the next feature. Having been in the industry for a number of years now this is what we keep saying, right? KISS. Wrong. Because KISS only works when there’s an overarching feature set you can keep things simple towards. With projects this young (code age, not idea age) and small (1500 lines of code, roughly) keeping things simple can lead to rather unpleasant discoveries. So in the past two months, whenever I got to working on fountain, I was working on rewriting the configuration system which initially was just not built out flexible enough (and used to be a singleton which ugh bad idea).

Fountain’s configuration system needs to accomplish a number of things.

  • It needs to be distributable – remember, there might be multiple repositories that make up one site
  • It needs to handle different sources. Configuration these days needs to handle environment variables, config files, and in the case of a markdown-driven system, of course frontmatter
  • It needs to be type safe across all input channels
  • It should be easy to use in code

What I came up with is not exactly a tree, but more of a nested list of lists. What do I mean by that? Suppose you have a root configuration object

1
2
3
4
5
name: My Blog
domains:
- localhost
- example.org
directory_index: README.md

There might be a situation where the directory index of some section of the site should in fact not be README.md, e.g. in a collection of posts. So in that case, you might create a separate config for that collection and in addition to the collection configuration override this one setting

1
2
collection_style: path
directory_index: auto

Both of these configurations will subsequently be available to fountain as layers under different ConfigLayerPaths, say root and blog_collection. Thus, when the router handles a registered collection route, it can easily switch the active configuration over to the blog_collection layer and subsequent config reads will correctly determine the desired values.

1
config.recomputeConfig(for: "blog_collection")

Loading and storing configuration is currently implemented for yaml. That however can be used to both read and write from a file or from a string that was extracted as a markdown frontmatter. Additionally, configuration options can be set to non-overridable. Layers with sub layers, say if we’re processing a post and are therefore in something like blog_collection.post_frontmatter[post_id] cannot be removed or modified until the sublayer is deactivated with another recomputeConfig.

Is this highly elaborate and a little over-designed? Probably. Does it solve my problems and is fun to use? Yep.

So here we are, it’s 2026, progress is happening at a slow but steady pace. Next up is integrating Git. I kind of scratched that whole hooks first and only plan from last time. Mostly because I stopped blogging for various reasons (see the February update) for a while and didn’t feel the pain of my current setup too much. But also, because I realised I don’t want to write something half-baked. Even if it takes longer, I’m sticking to the full-replacement route. That means, the 0.1 release of fountain is going to be a static site server with automatic git integration. That release may not be publicly available for a long time still. At the moment, I don’t have any plans to open source until I get close to the big 1.0. But as I regularly code on it again, there will be regular-ish updates here again, so that is something.

  • Published on February 28, 2026
  • 749 words