我为什么选择 Lua 用于这个博客
Why I chose Lua for this blog

原始链接: https://andregarzia.com/2025/03/why-i-choose-lua-for-this-blog.html

## 从摩擦到自由:我为什么用 Lua 重写我的博客 我博客之前的版本,先用 Racket,然后用 Pollen,变得过于复杂且难以维护。工作流程带来的摩擦大于内容创作的价值,本质上是试图强迫静态生成器充当动态网站。为了寻找更简单的解决方案,我最初考虑了 Javascript,但担心其生态系统快速变化——这是自托管博客系统常见的问题。 许多开发者难以长期运行他们定制的博客,并非因为固有困难,而是因为他们选择的技术栈演进速度*快于*他们的代码库。Javascript,尽管具有浏览器兼容性,却饱受其工具(NodeJS、NPM、库)不断变化的困扰。 我选择了 Lua,一种灵活且演进缓慢的语言。Lua 5.1 到 5.4 在 14 年间变化很小,这与 Javascript 的快速更新形成了鲜明对比。我使用 CGI 脚本和 SQLite 数据库重建了博客,优先考虑简单性和长期可维护性,而非性能。 Lua 体积小,依赖项少(目前所有项目共 29 个),这让我能够理解整个系统,避免“依赖地狱”。这种方法,秉承“选择平庸”的理念,旨在建立一个稳定、自包含的系统,我可以在未来几年内维护它。

一位博客作者(andregarzia.com)最近选择Lua作为其网站的脚本语言,并在Hacker News上分享了原因。 这篇文章引发了讨论,一位用户询问作者对Arturo的看法,Arturo是一种较新的语言,内置了全面的功能集(包括markdown解析和Web服务器),用Nim编写。 该用户强调了Arturo易于学习和社区支持良好,并指出他们之前曾用它开始了一个类似Hugo的项目,但后来放弃了。 另一位评论者询问作者为什么没有选择OpenResty。 原始作者表示会回答问题。 这篇文章还包含一个Y Combinator申请的公告。
相关文章

原文

This blog used to run using with a stack based on Racket using Pollen and lots of hacks on top of it. At some point I realised that my setup was working against me. The moving parts and workflow I created added too much friction to keep my blog active. That happened mostly because it was a static generator trying to behave as if it was dynamic website with an editing interface. That can be done really well — cue Grav CMS — but that was not the case for me.

Once I decided to rewrite this blog as a simpler system, I faced the dilema of what stack to choose. The obvious choice for me would be Javascript, it is the language I use more often and one that I am quite confortable with. Still, I don't think it is a wise choice for the kind of blog I want to maintain.

Talking to some friends recently, I noticed that many people I know that have implemented their own blogging systems face many challenges keeping them running over many years. Not because it is hard to keep software running, but because their stack of choice is moving faster than their codebase.

This problem is specially prevalent in the Javascript world. It is almost a crime that JS as understood by the browser is this beautiful language with extreme retrocompatibility, while JS as understood and used by the current tooling and workflows is this mess moving at lightspeed. Let me unpack that for a bit.

You can open a web page from 1995 on your browser of choice and it will just work because browser vendors try really hard to make sure they don't break the web.

Developers who built the whole ecosystem of NodeJS, NPM, and all those libraries and frameworks don't share the same ethos. They all make a big case of semantic versioning and thus being able to handle breaking changes, but they have breaking changes all the time. You'd be hardpressed to actually run some JS code from ten years ago based on NodeJS and NPM. There is a big chance that dependencies might be gone, broken, or it might be incompatible with the current NodeJS.

I know this sounds like FUD, and that for many many projects, maybe even most projects, that will not be the case. But I heard from many people that keeping their blogging systems up to date requires a lot more work than they would like to do and if they don't, then they're screwed.

That is also true about other languages even though many of them move at a slower speed. A friend recently complained about a blogging system he implemented that requires Ruby 2.0 and that keeping that running sucks.

I want a simpler blogging system; one that requires minimal changes over time.

Now we talk about Lua

Lua is a wonderful and nimble language that is often misunderstood.

One characteristic that I love about it, is that is evolves very slowly. Lua 5.1 was introduced in 2006, Lua 5.4 which is the current version initial release was in 2020. Yes, there are point released in between, but you can see how much slower it moves when compared to JS.

The differences between Lua 5.1 and Lua 5.4 are minimal when compared with how much other languages changed in the same time period.

Lua only requires a C89 compiler to bootstrap itself. It is very easy to make Lua work and even easier to make it interface with something.

JS is a lot larger than Lua, there is more to understand and more to remember. My blog needs are very simple and Lua can handle them with ease.

This is an old-school blog. I uses cgi-bin — aka Comon Gateway Interface — scripts to run it. It is a dynamic website with a SQLite database holding its data. When you open a page, it fetches the data from a database and assembles a HTML to send to the browser using Mustache templates.

One process per request. Like the old days.

You might argue that if I went with NodeJS, I'd be able to serve more requests using fewer resources. That is true. I don't need to serve that many requests though. My peak access was a couple years ago with 50k visitors on a week, even my old Racket blog could handle that fine. The Lua one should handle it too; and if it breaks it breaks. I'm a flawed human being, my code can be flawed too, we're in this together, holding hands.

Your blog is your place to experiment and program how you want it. You can drop the JS fatigue, you can drop your fancy Haskell types, you can just do whatever you find fun and keep going (and that includes JS and Haskell if that's your thing. You do you).

Cause I'm using Lua, I don't have as many libraries and frameworks available to me as JS people have, but I still have quite a large collection via Luarocks. I try not to add many dependencies to my blog. At the moment there are about ten and that is mostly because Lua is a batteries-not-included language so you start from a minimal core and build things up to suit your needs.

For a lot of things I went with the questionable choice of implementing things myself. I got my own little CGI library. It is 200 lines long and does the bare minimum to make this blog work. I got my own little libraries for many things. Micropub and IndieAuth were all implemented by hand.

At the moment I'm despairing frustrated having a lot of fun implementing WebMentions. Doing the Microformats2 exorcism extraction on my own is teaching me a lot of things.

What I want to say is that by choosing a small language that moves very slowly and very few dependencies, I can keep all of my blogging system in my head. I can make sure it will run without too much change for the next ten or twenty years.

Lua is a lego set, a toolkit, it adapts to you and your needs. I don't need to keep chasing the new shiny or the latest framework du jour. I can focus on making the features I want and actually understanding how they work.

Instead of installing a single dependency in another language and it pulling a hundred of other small dependencies all of which were transpiled into something the engine understands to the point that understanding how all the pieces work and fit together takes more time than to learn a new language, I decided to keep things simple.

I got 29 Luarocks installed here and that is for all my Lua projects in this machine. That is my blog, my game development, my own work scripts for my day job. Not even half of those are for my blog.

I often see wisdom in websites such as Hacker News and Lobsters around the idea of "choosing boring" because it is proven, safe, easier to maintain. I think that boring is not necessarily applicable to my case. I don't find Lua boring at all, but all that those blog posts talk about that kind of mindset are all applicable to my own choices here.

Next time you're building your own blogging software, consider for a bit for how long do you want to maintain it. I first started blogging on macOS 8 in 2001. I choose badly many times and in the end couldn't keep my content moving forward in time with me as softwares I used or created became impossible to run. The last two changes: from JS to Racket and from Racket to Lua have been a lot safer and I managed to carry all my content forward into increasingly simpler setups and workflows.

My blogging system is not becoming more complex over the years, it is becoming smaller, because with each change I select a stack that is more nimble and smaller than the one I had before. I don't think I can go smaller than Lua though.

By small I mean:

  • A language I can fully understand and keep on my head.
  • A language that I know how to build the engine and can do it if needed.
  • An engine that requires very few resources and is easy to interface with third-party libraries in native code.

I chose Lua because of all that, and I'm happy with it and hope this engine will see me through the next ten or so years.

联系我们 contact @ memedata.com