Visitar URL original
Entries

Why You Probably Don’t Need React (or any other frontend framework)

Beto Dealmeida

https://robida.net/

With the greatest respect, you're not Facebook. You don't have Facebook's problems. You might wish you had Facebook's problems, but your start-up with an MVP in progress and zero users just doesn't have the same demands of concurrency.

Somehow we ended up with AI because of all of this.

https://davegebler.com/blog/why-you-probably-dont-need-reactai

Beto Dealmeida

https://robida.net/

Building an open source ecosystem that works requires a lot of care. [...] The sourcecode is big and complicated, the developers are overworked and can't help users and newcomers, sometimes there is some elitism and gatekeeping driving people away. And then, a small group of people is left alone steering the ship. They are the ones who managed to jump all these hoops, and don't even notice how difficult it was to get there, or maybe it was easy when they did it and it became more complicated later on.

I can see this. Especially at work, when someone joins a company and is tasked with working on a huge and complicated repo β€” they can be "productive" from day 1 by using LLMs. They don't have to understand the code base, so they skip that phase, and soon no one can understand anything without the help of AI anymore. If code was simpler, decoupled, modularized, well documented and with well defined interfaces, then it's likely that people could be productive from day 1 without having to resort to LLMs.

I think we will be better off in the future with more smaller projects like that. Something a person can understand and manage.

I think so too. I recently migrated to NetBSD on an old Thinkpad X250, and switched to Forth and Tcl for programming. My online world become smaller: sites don't work on my browser, I don't use Instagram, I don't listen to Spotify. But there's still so much content, so many amazing people that can be reached via email, RSS, Gemini, webmentions, lynx. I've been really happy with downsizing my tech stack.

https://robida.net/entries/2026/09/01/building-an-open-source-ecosystem-that-works-requihttps://pulkomandy.tk/_/_Life/_Debian%20has%20fallenlinuxai

Static pero no mucho

Beto Dealmeida

https://robida.net/

There are two different approaches to running a personal website: static or dynamic. They each have their pros and cons, but there are some ways to bridge the gap between them.

Static websites

Static websites are generated by running a program that generates HTML files, as well as CSS and Javascript. The generated files can then be uploaded to the web, usually for free. People use GitHub pages to host their websites for free, and some people use Amazon S3 for a very cheap solution. I think the most popular static site generator (SSG) these days is 11ty. A few years ago I used to run my own SSG, called nefelibata.

The biggest advantage of SSGs is that it's easy to host the website. They are just HTML, so it's easy to cache or put in a content delivery network (CDN) to ensure the website is never down. It's a very resilient solution, trivial to backup and move from one provider to another. It's just files that never change.

And that's the biggest disadvantage with static websites: it's just files that never change. To add support for comments, webmentions, and other interactions, you need rely on an external service. For people who care about self-hosting, like I do, that becomes a challenge.

Dynamic websites

Dynamic websites are websites that depend on software running on a server, and usually rely on a database. If that sounds daunting, you've found the main disadvantage that they have. They require maintenance, and are hard to scale: if someone shares a link to one of your posts on a popular website, it's very likely that your website will go down.

They're also more expensive to run, in general. People usually rent a virtual private server (VPS) on a cloud provider, which costs around $4-20/month. They can be hacked, so now you have to be a 24/7 sysadmin making sure the system is secure and stable.

The biggest advantage of dynamic websites is that they're alive. If someone leaves a comment it can show up immediately to other visitors. You can configure your website to receive webmentions, or to send webmentions when you create a new post. It can send you notifications when someone likes one of your posts. The level of interactivity that you can achieve is much higher, compared to SSGs.

My current website is dynamic: it runs Python on a $5/month VPS. When I weight myself on my smart scale the data is automatically sent to my blog, creating a private post. It's the same thing when I play a video game on Steam. All of these interactions would be impossible with an SSG.

Funky caching

Are there any in-betweens? I remember discovering funky caching back in 2002. It worked by generating a static version of a page the first time it was requested. Subsequent requests would read from the generated static HTML, reducing the load on the server. If something changed on the website β€” for example, you added a new post β€” you would have to delete the old, stale, pages.

It was not popular, and to be honest I don't remember what problem it was trying to solve. Wouldn't it be easier to just generate the whole website when a change happened, instead of deleting the files and waiting for them to be built during requests? Maybe the time to generate all the static files was too big back then; these days modern SSGs can regenerate a whole site in milliseconds, when written correctly.

Back then I used a blog engine called PyBlosxom, and I added support for funky caching. I also wrote a Wiki engine called "kikiki" that leveraged the concept: whenever you visited a non-existing page it would show a form to create it, instead of returning a 404.

My new blog

In the new blog engine I'm writing, each page is a program. When you run the program, it generates HTML. But because the program is written in Forth, the programs look a lot like HTML with templates. I have a Makefile that runs all the Forth programs it can find, in order to build a static version of my website: the index.fs program generates index.html, pages/likes.fs generates pages/likes.html, and so on.

So it's an SSG?

It is static. But it also has one endpoint that is dynamic. The website runs a single Forth program as a CGI file, exposing an endpoint for visitors to like posts and leave comments. Those interactions are saved into a CCSV file, that is read by the individual pages in order to render them along my posts.

The problem is, once a visitor leaves a comment, how do we make the new comment show up on the page, if it's static? One way to solve this, which is how I initially solved it, is to have Javascript code accessing the endpoint to read the comments for a given post. This works well: a visitor opens a page, the page renders with some comments, and any new comments are loaded from the dynamic endpoint and displayed in under a second.

But it doesn't work for everyone. Some people don't have Javascript. I'm from a time when we celebrated progressive enhancement, when pages worked without Javascript and, instead, relied on Javascript only as a way of improving the user experience. And while the big corporate web is way past progressive enhancement, we're talking about the indie web here, the punk web, grassroots websites & al. I want to make a website that works on lynx.

How does it work without Javascript? Without Javascript, the CGI bin stores the like/comment in the CCSV file and then calls the original page to re-render the HTML. It doesn't even need to spawn a process: it's just a Forth program (the CGI bin script) calling another Forth program the page, which can be done with an include directive. And because it's Forth, it's fast: rendering a page takes ~7ms in my 11 year old laptop running NetBSD.

After rendering the page, the CGI bin script then redirects the user back to the fresh page. So the website is static, but it has a single endpoint for POST requests that recompiles the static pages as needed. Deployment is still relatively simple: it requires a gforth and a web server with support for CGI (I'm using bozohttpd), but no database.

web

Blaugust summary

Beto Dealmeida

https://robida.net/

I posted 23 times during Blaugust, which is not bad! You can check it yourself by going to https://robida.net/sql and running this query:

SELECT uid, json_extract(content, '$.properties.name[0]') as name
FROM microformats2
WHERE
  deleted_at_hlc IS NULL AND
  author='https://robida.net/' AND
  visibility='public' AND
  post_status='published' AND
  NOT content LIKE '%repost-of%' AND
  NOT content LIKE '%follow-of%' AND
  created_at > '2026-08-01' AND
  created_at < '2026-09-01'
ORDER BY hlc_timestamp DESC

Don't worry, you can't mess up the DB. That's your copy, it lives in your browser, and should only contain public posts. If you delete, create, or edit entries you will be the only one who will see them, with one exception: if you're logged in to my site, any entries you create in your local DB with an author equal to your login will be synced to the backend. This means you can delete every interaction you've ever had with my site (likes, replies, even posts from my feed reader that were authored by you!) with this SQL:

UPDATE microformats2
SET deleted_at_hlc = CAST(unixepoch('now', 'subsec') * 1000 AS INTEGER) << 16 | 0
WHERE author='https://alice.example.com/'  -- your login

Note that if you DELETE entries, instead of setting deleted_at_hlc, they won't be synced to the backend, and they will likely show up again in your browser in the future.

⁂

I think the only reason why I didn't get to 31 posts is that I've been spending a lot of my free time working on my new blog, the "hand-written GForth DSL for writing web sites" that I call Quintana. I'll be deploying that in the next few weeks, and it's been super fun to work on it.

meta

Your CMS should be a garden, not a pot

Beto Dealmeida

https://robida.net/

In my blog I track (poorly) the books that I'm reading, have read, or want to read. To add a new entry to my read list, this is the current workflow:

  1. I click "Compose", and I'm greeted with a new page with big empty text inputs.

  2. I choose "Read" as the type.

  3. I then fill in the information about the book:

    1. Title

    2. Author

    3. ISBN

    4. Status (to read, currently reading, finished)

    5. Review or notes

    6. Tags

And here's how it works in my new blog (work in progress):

  1. I edit a file called books.fs and add the information about the book to the right section, depending on the status.

These two workflows might seem very similar, but I noticed a very interesting difference. In the first one, I'm tending the entry like a plant in a pot: all I see is the plant. But on the second one, I see a garden: all the other book entries are right there, in the same file. When I add a new book, I can place it next to another book by the same author. Or I could leave a comment saying something like "this is the third book about architecture that I read this year". Maybe I see a typo in the name of an author and quickly fix it, maybe I want to add a reference between two books.

I'm not a gardener, but it does feel like taking care of a garden: the plants live together, they interact, and one might be casting too much shade over another, so let's fix it!

https://news.indieweb.org/en/robida.net/entries/2026/08/27/your-cms-should-be-a-garden-not-a-potgemini://robida.net/entries/2026/08/27/your-cms-should-be-a-garden-not-a-potcms