We should bring that back! Its such a great way to play around with client- and server-side development options in an almost zero-risk environment.
https://github.com/williamcotton/webpipe
My blog code:
https://github.com/williamcotton/williamcotton.com/blob/mast...
GET /hello/:world
|> jq: `{ world: .params.world }`
|> handlebars: `<p>hello, {{world}}</p>`
describe "hello, world"
it "calls the route"
when calling GET /hello/world
then status is 200
and output equals `<p>hello, world</p>`What is the typical learning project these days for beginners of a programming language?
In hindsight, it was a horrible way to learn. Most YouTubers probably benefited more from clickbait teaching than from actual fundamental teaching. Eventually, I was able to navigate the internet and land on an actual structured curriculum, whose lectures and courses were long and boring but taught you the fundamentals of programming.
I am picking up a similar pattern with Vibe Coding. Beginners are more excited about having a launched product wrapped with a band-aid rather than having deep knowledge.
The blog/data directory can be backed up or even using a github repository for long term raw storage.
I'm not a fan of having the same site/application for rendering as editing the blog as it tends to become too much of a big/easy target... ie: Wordpress, how much internet traffic is script bots trying WP exploits?
Obviously don't go rolling your custom CGI scripts on a server that also hosts your personal email - but these days we are spoiled for choice in terms of isolated hosting strategies for a blog.
Heroku, Vercel, Cloudflare Workers, Fly.io, GitHub Pages, a $5/month VPS...
If you roll your own little cgi-bin perl script behind Apache you're far from vulnerable compared to, say, a WordPress website.
1. nobody cares 2. its not that complicated to write a dynamic web page that isn't going to get pwned
All to say I think if long term compatibility is the primary goal there are probably better languages.
Have you already discounted php or perl?
NeoVim is committing to 5.1 and leaving it at that.
I guess I'm not sure what advantage lua has in that regard: you could stick to an old version of any language, including node, which was called out as being hard to keep up with.
https://www.lua.org/versions.html
You can see that between 5.3 and 5.4 there were five years. 5.2 to 5.3 was also a five years gap.
Breaking changes are well documented and we see them years before they happen and nothing requires you to upgrade.
Most code runs on 5.1 forward.
* to minimize dependencies. Lua < Lua + Fennel. I'm more extreme than OP in that I don't even use LuaRocks. When I need a library I copy it in, and I pick a library that won't change often so that is a reasonable approach. I try to avoid native libraries.
* for even greater stability. Fennel is pretty stable, but I use Lua 5.1 for the most part which hasn't changed since 2008 or so. I'm more extreme than OP in even avoiding later versions of Lua.
Bottomline: the reasons I like Lua have nothing to do with syntax and are much more about these operational meta characteristics of the language. If I cared more about syntax I'd be on Fennel in a heartbeat.
A shell function is enough to call pandoc, update any kind of index (date or tag based) and an rss page really. I would hardly call that an engine, it is just an helper to not forget to update indexes and feeds.
[1] loading speed was the main reason blog engines used to split posts in single pages
PS: I'm the author.
I can't imagine needing more than that. Why are these blog stacks so complex?
Admittedly most of my blogging history has been something of a path towards simplification from hand-rolled PHP+MySQL, with custom "forum code" markup language, stuff before "blogging" was even an agreed upon term for it (and before Markdown was anywhere near as pervasive), to complex third-party beasts like Drupal, to homegrown Python (and reStructuredText), to very simple SSG tools (these days still Jekyll, but I don't like working in Ruby much, so I keep debating a switch to Lume but I don't think its Redirects plugin is yet compatible enough with GitHub Pages for my liking and I haven't tested its RSS support yet, both of which are personal hard requirements).
Preferably with full content unless you're doing some Substack personal branding "subscribe to my paid newsletter" -crap.
1. I don't want to rely on any external SaaS but my VPS. No github action to rebuild the site or anything like that.
2. I want to be able to post from multiple devices, which means that SSGs add more friction cause I'd need to make sure the source is up to date on all machines I am trying to post. It is not a hard problem, but opening an editor online and posting is much easier. The key to blogging is reducing friction.
cmark
dkjson
etlua
hasher
lsqlite3
lua-markdown-extra
luafilesystem
lub
lustache
multipart
penlight
uuid
yaml
http
gumbo
sleep
bbcode
cookie
Many of the dependencies are there to support the posts that are legacy posts coming from my previous SSG. I imported them into the database and they require Yaml and other dynamic features. Some dependencies like gumbo, http, multipart are all there to support indieweb features such as webmentions and micropub.It basically costs nothing to pre-render a static site, which then serves several orders of magnitude faster. I'm confused why anyone would do it this way in this day and age.
I considered monitoring popular posts and prerendering those. Feels like code bloat for something that might not happen.
Don't get me wrong, this blog used to prerender everything. It kinda sucked to compute which pages were affected by a change in any given page as it might need to patch indexes, cross linked references, and so on. It can be done of course, or you can simply re-render everything anyway. The added friction for development and maintenance was not worth it for me.
It is my personal blog, it is not a personal branding site to show people my cool web skills or anything. If it goes down, let it go down.
I know some will go 'oh well I want a web interface to create or edit posts in', nothing says you cant just implement that part dynamic and have it update static components on modification of posts.
> Your blog is your place to experiment and program how you want it
I 100% agree with your statement and people don't need to justify their hobbies. I've done really pointless things simply for lolz and because I wanted.
My question arises because I was surprised in how ... architected and (dare I say) complex the tech stack in your blog is. In my blogging days I wrote my own HTML/CSS and published it on a Internet facing server. Later, I've used CSS templates and Markdown-to-HTML to generate the static content. What is the purpose of Lua and having a database and all the other complexity for what seems like a static blog? Again, "because I wanted to experiment" or "sharpen my skills" is a totally valid answer but seeing I don't have a background in web development I am inquiring to see if there is a technical reason for doing this. Would be curious to learn what, if any, technical problem warrants such a set up :)
The stack doesn't feel as complex to me because I know it well. Familiarity doesn't make it less complex but make it comfortable. The reason for the database is that it allows me to run queries. It makes it easier for creating "recent posts" and "posts with this tag" pages.
Lua is the glue that ties it all together. Yes, HTML/CSS can be used to create a full site but writing posts in HTML gets tiresome fast when typing on a phone for example. The way it is it has an admin interface that allows me to write markdown on my phone or edit a post. It is handy.
For my own personal projects it is less about technical reasons and more about what will make me happy. What brings the joy on and less about what is the optimal solution.
Does that makes sense?
I know its definitely smaller but I just want your opinions on it and what you might think of the language and I may be a bit sorry if this comes across as a little off topic but your blog really reminded me of arturo and my attempts on creating something like hugo in arturo but the project was abandoned mid way but if I remember correctly it was just some 50 lines of code to convert from markdown to complete website or even less since arturo's battery include markdown syntax as well as well as a web server and its written in nim which I cherish too.
I am genuinely interested in your opinions about it!
I might play with it for some project in the future.
https://arturo-lang.io/documentation/in-a-nutshell/
It looks interesting.
Fennel is absolutelly amazing, I love it. I just didn't had the need. I like Lua the way it is. I was a student at PUC Rio for a while, I fell in love with it there and am very familiar with it.
I think what is really meant by choosing boring technology is that it be simple, proven, reliable.
That's the key part. Minimize cognitive load, maximize peace of mind.
Some ecosystems are "boring" in the sense that developers are not excited about them, but they also maximize your blood pressure and chance of shipping defects. That's the wrong kind of boring!
easy ≠ simpleThere's also the venerable MoonScript: https://moonscript.org/
And YueScript, a personal fave: https://yuescript.org/doc/
A whole list: https://github.com/hengestone/lua-languages
When you're doing stuff in nvim or HammerSpoon, you're dealing with someone else's interface and the decisions that they've made.
> I find Lua simple
The comment you've replied to is correct: "easy ≠ simple". Lua is indeed simple, but it chooses simplicity over ease-of-use. For example, even printing the contents of a table requires explicit logic.
OTOH Python, for example, prioritises ease-of-use: `l = [1, 2, 3]; print(l)` does what you'd expect. But Python only achieves this ease at the expense of simplicity: not only does the implementation of `print` need to be more complex, its output can be complex and unpredictable as well - for example, in the case where `l` refers to itself.
Of course it has its warts, but given the topic, almost everything is better than a vimscript imho.
0-indexing makes sense in the context of C where the index operator is syntactic sugar for pointer arithmetic. In higher-level languages like C# and Python and others, it's pretty much just a leftover habit from C devs that we all got used to.
Global by default is a perpetual issue, agreed.
In fact, at least for this application I've come to enjoy its practicality!
https://andregarzia.com/2021/01/lua-a-misunderstood-language...
I like 1 based indexes and the globals don't hurt me on my projects. It is like JS, it has its own bits that are different than other languages, once you learn them you see that it is mostly fine.
I found it surprisingly good and considering how little I know on how to use HTML/CSS/JS/PHP, the usual web stack, it would have taken me months or more to learn how to build an equivalent site using the standard stack (and then have to maintain it).
Of course, if you're already familiar with web development, that's the best way I guess, but for those who aren't and don't have the necessary time to learn, there are probably alternatives using languages they're familiar with.
But couldn’t anything you say about Lua also be said about JS? You mentioned how Lua wasn’t batteries included, so you try to limit your libraries. Couldn’t you say the same for JS? JS itself doesn’t change much, it’s the ecosystem. Couldn’t you just pick out some small and stable libraries the same way you could with Lua?
Golang has one of the best developer experiences and there are only very very few minor nitpicks I might have of the language but the whole ecosystem on packaging software and what not is just so easy and I love golang.
Only problem is I have language ADHD. I use way too many to pick up another like Lua.
Yes, I could have picked a js runtime and done the same thing. The same thing could also have been done with literally any other language.
It is less of a "Only Lua Can Do This" situation and more of a "I Like Working with Lua" situation.
It’s so cool to take the interpreter source, type make and be using it in one minute.
I considered switching to Lua (actually Fennel) but luarocks can be fiddly to use across platforms (I now run everything on ARM servers) and that pretty much was the end of that. So I’m curious as to how maintainable a Lua back-end is over time.
xsltproc was preinstalled on my machine actually, the fact I could just run it without installing anything is pretty cool
<xsl:choose>
<!-- ... other code -->
<xsl:when test="name(.) = 'subsection'">
<xsl:choose>
<xsl:when test="not(boolean(ancestor-or-self::*/@next)) or ancestor-or-self::*/@next != 'rev'">
<xsl:if test="boolean(following-sibling::subsection[@listindex != 'no']/attribute::directory)">
<link rel="next" href="../{following-sibling::subsection[@listindex != 'no']/attribute::directory}" title="{following-sibling::subsection[@listindex != 'no']/child::title}"/>
</xsl:if>
<xsl:if test="boolean(preceding-sibling::subsection[@listindex != 'no'][position()=1]/attribute::directory)">
<link rel="prev" href="../{preceding-sibling::subsection[@listindex != 'no'][position()=1]/attribute::directory}" title="{preceding-sibling::subsection[@listindex != 'no'][position()=1]/child::title}"/>
</xsl:if>
<link rel="first" href="../{../subsection[@listindex != 'no'][position()=1]/@directory}" title="{../subsection[@listindex != 'no'][position()=1]/title}"/>
<link rel="last" href="../{../subsection[@listindex != 'no'][position()=last()]/@directory}" title="{../subsection[@listindex != 'no'][position()=last()]/title}"/>
</xsl:when>
<xsl:otherwise>
<xsl:if test="boolean(preceding-sibling::subsection[@listindex != 'no'][position()=1]/attribute::directory)">
<link rel="next" href="../{preceding-sibling::subsection[@listindex != 'no'][position()=1]/attribute::directory}" title="{preceding-sibling::subsection[@listindex != 'no'][position()=1]/child::title}"/>
</xsl:if>
<xsl:if test="boolean(following-sibling::subsection[@listindex != 'no']/attribute::directory)">
<link rel="prev" href="../{following-sibling::subsection[@listindex != 'no']/attribute::directory}" title="{following-sibling::subsection[@listindex != 'no']/child::title}"/>
</xsl:if>
<link rel="first" href="../{../subsection[@listindex != 'no'][position()=last()]/@directory}" title="{../subsection[@listindex != 'no'][position()=last()]/title}"/>
<link rel="last" href="../{../subsection[@listindex != 'no'][position()=1]/@directory}" title="{../subsection[@listindex != 'no'][position()=1]/title}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- ... other code ... -->
</xsl:choose>
And yes, there is other code I've omitted for brevity. This is used to generate the navigation links for the site. I initially write this ... prior to 2009 (that's when I moved it into git). There have been some minor fixes to the XSL over the years, but it's largely unchanged (for a reason that I hope is obvious). Yes, I still use it, because it still works, and it's for a static website.You can spin up a node server yourself and use web components and it will run fine probably just as long as the lua code will. It's also way easier today to just use web components and not any framework since LLMs can help you speed up the development.
(For years now I publish with Hugo/Bunny CDN ($1/month))
I from time to time wonder if I should write my own engine. Then I laugh and write a blog post.
For example, take Javascript. With a runtime like Bun, you would have the primitives to serve some HTTP and talk to SQLite right there in the core. And here's the good news, if you carefully implement only the things that you need for your project, you probably don't need NPM. You can write it all on your own, you can peek at how NPM authors solved the problems you run into, but you still can make it all your own. This would leave you with this amazing retrocompatible language with lots of mindshare to boot.
Really, you don't need that whole ecosystem if you're solving your own problems and are not required to interface with someone else's library. And no one is forcing you to use it.
Or you could take Python, and it has a few single-file web frameworks. You can go with one of them and the standard library a very long way. No one tells you you must use any of FastAPI, Jinja, Flask, Django (anyone remembering Pyramid?), SQLAlchemy...
Or you could write it in Go, SQLite module being your only external dependency. You can even pin your go.mod to a particular version of the compiler so you're not bothered with incompatible changes, or changes at all.
Or, you could whip up Perl... but yeah. CGI.pm and DBD::SQLite are not in the core. And anything else has a litany of CPAN dependencies with their quirks. No, don't whip up Perl.
All I'm saying there's nothing that makes Lua somehow inherently more suited to your philosophy than any other mainstream language. Except maybe to be different. And you're still pulling in 29 luarocks, aren't you?
I used to like moonscript coffescript-like syntax, but nowadays I mostly like plain lua, though Fennel looks appealing.
I've been converting my Bash scripts/functions to it, with much success thus far.
JIT-compiled languages aren't generally faster in starting up, they generally are used to speed up long-lived programs that have hot sections.
It wasn't until LuaJIT that I realized that JIT didn't inherently have to be these slow lumbering beasts that take hundreds of milliseconds just to wake from their slumber.
You know what the new interesting hotness might be? Getting the LLM to write wasm (via wat, its textual analog), and running that with https://wazero.io/ , which is astonishingly fast (although still not as fast as luajit for some reason, despite being lower-level), but also gaining multiplatform without recompile in the process
https://github.com/dbohdan/caddy-markdown-site/blob/master/C...
^^ the above combined with caddy git fs to have your md files cloned in memory and refresh every X interval is kind of magical. Git push a new md file and wait X minutes and your website updates.
https://github.com/mohammed90/caddy-git-fs
====
Or a one-file FastHTML (python web framework) solution:
https://gist.github.com/simonMoisselin/f63c52f087704c99b6a62...
A large proportion of users may very well be on mobile, but do we just not do flexible layouts in 2025?
I guess this is his why ;-)
I worked briefly professionally in Julia a couple years ago, which is 1-indexed, and I found it an easy transition, really. Many scientific computing things are 1-indexed, as Fortran was, too, among other reasons.
My own project is a rewrite / defibrilation of the 1990s LambdaMOO server (https://codeberg.org/timbran/moor/), which had its own OO programming language that was 1-indexed.
It's just not as "weird" as people think, I think it's just a generation of people grew up with C-derived languages and have grown to expect 0 as "normal" when it's really just "accident of history/popularity". I don't think it's objectionable that Lua chose 1-indexing, it is actually more "friendly" to newcomers to programming.
Totally valid choice to make, but in my opinion OP is missing out. OpenResty is state of the art and has a ton of great libraries embedded in it. It's "batteries included" so to speak, and the batteries are well designed. Yichun Zhang is one of the GOATs, along with Mike Pall. And Roberto, obviously.