A Forth-inspired language for writing websites

https://lobste.rs/rss Hits: 56
Summary

I don't remember where the idea came from, but I decided that it would be cool if I could write websites using a stack-based language. Something like this:: h1 ( s -- ) "<h1>" emit . "</h1>" emit ; "Hello, World!" h1So I wrote Forge.I quickly built a library of word definitions that let me easily add microformats to the HTML:: post-content "Hello, world! This is my first post with Forge!" p ; : post-body h-entry-start "<p class='byline'>" emit "2026-05-21T14:00:00Z" "May 21, 2026" dt-published " · by " emit "Beto" "/about" p-author "</p>" emit h-entry-end "On building a tiny stack-based web language." p-summary "post-content" e-content "/hello-world" "permalink" u-url ; "Hello, world!" "post-body" blog-postEach site is a collection of pages, a library of words, and a stylesheet:my-site ├── lib.forge ├── style.css └── pages ├── about.forge ├── hello.forge └── notes.forgeA single binary runs the website:forge --log forge.log my-site/The binary does a lot. It has a webassembly compiler that generates HTML from .forge files. When you visit a page the compiler runs on the backend, and you get the actual HTML in the source code, as well as the original .forge source. But when you navigate between pages, a service worker captures the network request to the page, say, /notes, fetches the source /notes.forge), and builds the HTML on the fly by running the compiler on the browser. So we have server-side rendering for crawlers and WebMentions, and client-side rendering for a SPA experience.I love the limitations of the language. You can persiste things to state, localStorage, or to an append-only log on the server. For example example, I can add a "like" button to posts like this:: like-button ( -- ) "❤" "do-like" on-click ; : do-like "1" "likes:demo" log-append ; : body "I liked this!" p like-button ;When you click it, appends the value "1" to the topic "likes:demo" in the log. It's just JSONL (one JSON document per line). Forms can submit to other .forge pages, and they simp...

First seen: 2026-05-22 14:21

Last seen: 2026-05-23 23:45