Dev.to WebDev 🛠 Dev 👁 1 📖 5 min read

Your blog posts should be files you own, not database rows or Git commits

Every time I set out to start a new blog, I run into the same thing: there are really only two options, and neither of them feels right. One is WordPress. First you stand up a server, run PHP, put MySQL next to it, and

Your blog posts should be files you own, not database rows or Git commits

Every time I set out to start a new blog, I run into the same thing: there are really only two options, and neither of them feels right.

One is WordPress. First you stand up a server, run PHP, put MySQL next to it, and babysit the configuration of both. Once it is finally running, the plugins begin. You add this one and that one, wrestle with dependency and version combinations, and brace yourself every time you update in case something breaks. The clincher: the default login URL is fixed at /wp-login.php, which means everyone on the internet already knows where the door to your admin panel is. So you install yet another plugin to keep the bots out. All you wanted was to write a post, and somehow you are now operating a system called WordPress.

The other option is a static site generator like Hugo or Jekyll. There is a lot to like here. It is fast, and there is no database. But every time you fix a single post, you make a Git commit. Six months in, your commit history is a sediment of "fix typo" mixed with "refactor the app." The act of writing comes bundled, every time, with the rituals of version control.

With both, all you actually want to do is write, yet you end up carrying far too much. That is how it felt.

To be clear, WordPress, Hugo, and Jekyll are all excellent, admirable systems, and this article is not here to tear them down. It is here to propose a different shape.

As that alternative, I built an open source blog system called Baan.

https://baan.press

The body of a post should be a file, not a database row or a Git commit

When you boil the discomfort down, it all comes back to one question: where does the body of a post live?

Where the post body lives
Traditional CMS (WordPress, etc.) As a database row. You have to run a server and a database.
Static Generator (Hugo, etc.) As a Git commit. History gets mixed in with your code.
A third way What this article proposes: a Markdown file in storage you choose (only metadata in a DB).

In Baan, the body of each post is a plain .md file kept in storage you choose (a local filesystem, S3, GCS, or R2). Only the operational data, such as metadata, settings, and the post index, lives in libSQL / Turso / SQLite. You do not have to stand up and run a MySQL or PostgreSQL server yourself.

Because of this, a post stays "just a file" all the way down. You can open it in any editor, and you can copy the whole thing and take it with you. Your Git repository is only for application code and themes, so its history never gets muddied by post commits. And since it runs on serverless as well as in a container, if you put it on a platform like Vercel you do not keep maintaining a server yourself (the managed libSQL/Turso and cloud storage hold the data).

Archtecture of Baan

How you write

1. Write in an editor with an AI assistant

Baan has an editor with a built-in AI assistant. Drafting, proofreading, fact-checking, and even FAQ generation can all be done without leaving the editor. You can pick between Claude, OpenAI, and Gemini, and switch anytime from Baan Admin. Because it is open source you set your own API key, but it will genuinely help you write.

Multiple languages are supported out of the box, with content across 11 locales. Write in your main language and you can translate with AI from there.

If you want the most fully-equipped place to write in Baan, this editor is where to start.

Baan Editor

2. Write in the editor you already use, and publish with the CLI

That said, once you take "a post is a file" to its conclusion, you are not tied to a single writing tool. Obsidian, Typora, VSCode: write in whatever you already use. When you are done, sync with the CLI.

https://github.com/baan-press/baan-cli

https://www.npmjs.com/package/baan-cli

Only the changed files are uploaded as a diff, and images referenced in a post are carried along with it. Whether you write in the Baan Admin editor or in an external one, you end up in the same place: a .md in your own storage.

The initial setup is just this:

npm install -g baan-cli
baan init             # Set API URL and CLI key interactively
baan sync ~/vault     # Differential sync of a local directory

I actually like Obsidian, but Publish requires a paid plan and never felt flexible enough, and that is part of what led me to the Baan approach.

The things you will want in 2026, built in from the start (I hope)

The lead role is still "a post is a file," but once you actually run a blog, other things start to matter. Baan bakes those in from the start rather than bolting them on as plugins.

Take security. As the flip side of the /wp-login.php story above, Baan randomizes the admin login URL by default, and offers IP restrictions and Basic authentication for the admin panel as standard. Things that ought to have been the default are the default.

It also takes the AI-era traffic seriously. Beyond search engines, how do you handle AI crawlers like GPTBot and ClaudeBot, and how do you make AI-sourced traffic visible?

Baan Bot management

There is also a knowledge graph that captures the relationships between posts as entities, so it can recommend the next post a site needs. For storage, you can use a server filesystem just like a traditional CMS, or choose S3 / GCS / R2 from the start.

Knowledge Graph

What you write should be yours

In the end there is only one thing to say. What you write should not live inside a platform, a database, or a Git history. It should live in files you own. And a writer should be able to spend their time writing, not maintaining a server.

More here:

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.