RSSAmplifier

Blog

Loopwerk

loopwerk.ioRSS feed ↗150 posts

Latest posts

Apple blames the DMA again

Apple keeps telling EU users that the DMA is the reason they can't have the latest features. But the reality is that Apple doesn't want to open up, so nobody gets it.

uv is fantastic, but its package management UX is a mess

uv's CLI feels surprisingly clunky compared to its peers like pnpm or Poetry.

Announcing Scry

Scry is a pure-Swift, dependency-free, and fully Linux-compatible EXIF parser.

Coding with AI: productivity without pride or joy

I just finished my most productive quarter in a long time, made possible by Claude Code, and there are two conflicting feelings that I want to talk about.

Q1 2026 in review

Normally I just stick to my once-yearly "year in review" articles, but the first three months of this year have been so productive that a Q1 update seems warranted.

Announcing Saga 3 and Parsley 1.2

Saga 3 brings much faster builds and a more flexible pipeline, while Parsley 1.2 adds powerful Markdown attribute support.

Building modern Django apps with Alpine AJAX, revisited

Nine months after adopting Alpine AJAX with Django, I've gone through template partials, Jinja2, and landed on an approach that's both fast and clean.

The shortcomings of Swift Package Manager

As I prepare Saga 3, I keep running into fundamental limitations in Swift Package Manager that make maintaining a plugin ecosystem unnecessarily painful.

Announcing GetSaga.dev

I've created a brand new documentation website for Saga, built with Saga itself. It features full API reference docs, works without JavaScript, and looks pretty great.

Announcing SwiftTailwind

I've created a Swift package that wraps the Tailwind CSS standalone CLI, removing the need for Node.js or npm in your build pipeline.

Announcing SagaUtils

A collection of reusable utilities for Saga, extracted from this very website: composable HTML transformations and useful String extensions.

Announcing Bonsai, a new HTML minifier in pure Swift

I've created a new HTML minifier in pure Swift, with zero dependencies and performance on par with the best Node.js minifiers.

Protect your analytics with Cloudflare

How I used Cloudflare's free security rules to filter bot traffic from my self-hosted Umami analytics.

Umami vs Plausible: why I switched

After leaving Plausible I moved to Umami. Here's what's better, how I set up proxying to bypass adblockers, and the one problem neither tool can solve.

Self-hosting Plausible broke my analytics

After years on Plausible I switched to self-hosting and discovered just how much they hold back from their open source version.

The software and hardware I use

This is the stuff I use daily for development, photography, and gaming.

Announcing the Saga CLI

Saga now has a companion CLI tool, installable via Homebrew or Mint, with commands to scaffold a new project, build your site, and run a dev server with live reload.

Prevent your Coolify deploys from randomly starting without a build cache

If your Coolify deployments are sometimes fast and sometimes mysteriously slow, Docker's BuildKit garbage collection is probably silently deleting your build cache.

A real-world comparison of static site generators: Hugo vs Publish vs Saga

I built the same site with Hugo, Publish, and Saga to compare how each static site generator handles real-world requirements.

It's time to leave Heroku

Heroku just announced it's entering "sustaining engineering mode". No more new features. After years of security breaches, outages, and price hikes, it's time to leave.

Tim Cook sold Apple's soul

The company I once admired has become morally bankrupt, but leaving the ecosystem feels almost impossible.

Django's test runner is underrated

I never made the switch from unittest to pytest for my Django projects. And after years of building and maintaining Django applications, I still don't feel like I'm missing out.

Announcing Moon, a new HTML syntax highlighter for Swift projects

I've created a new Swift package that does server-side syntax highlighting of HTML content, using Prism.js.

Django 6.0 Tasks: a framework without a worker

Background tasks have always been essential in Django projects. Django 6.0 finally acknowledges that fact, but its new Tasks framework stops short of what real apps need.

Expertise is the art of ignoring

Trying to "master" a programming language is a trap. Real expertise comes from learning what you need, when you need it, and ignoring the rest on purpose.

My Home Assistant setup

Let's dive deeper into my Home Assistant setup. How do I sync everything to Apple's Home app, and how do I automate things.

Home Assistant review after one year of use

Nearly a year ago I replaced a pile of smart-home apps, hubs, and subscriptions with Home Assistant Green. This is my long-term review.

2025 in review

Let's get into personal stuff, freelance work, and open source projects.

Safe Django migrations without server errors

How to run schema-changing Django migrations safely, avoiding schema/code mismatches and server errors during rolling deploys.

An ode to the tester

Here's to the curious ones. The bug finders. The rebels of the happy path. The round pegs who try every square hole just to see what breaks.

My #1 rule for lasting side project passion

What if the secret to a thriving side project isn't more expertise, but less overlap with your day job?

Async Django: a solution in search of a problem?

While a technical marvel, async Django has been quietly rejected by the community it was built for, with the vast majority of developers sticking to simpler, proven solutions.

Run Django tests using PostgreSQL in GitHub Actions

Did you know that you can run unit tests for your Django app, in GitHub Actions, using PostgreSQL?

Announcing spamusement.cc

Remember the brilliant webcomic Spamusement.com? It ran from 2004 to 2007, but sadly the website went offline in 2020. I missed it so much that I put online an archive.

Django views versus the Zen of Python

Django's generic class-based views often clash with the Zen of Python. Here's why the base View class feels more Pythonic.

One command to run them all

How I use the just command runner to create a simple, unified interface for running, testing, linting, and formatting all my projects, regardless of the tech stack.

A quarter century of chasing simplicity

A reflection on 25 years of web development, from simplicity to complexity and back.

How I write Django views

Why I only use Django's base View class instead of generic class-based views or function-based views.

Announcing django-generic-notifications 1.0.0

A modern, flexible rewrite of django-generic-notifications is here. Easily send website and email notifications, create digests, group similar messages, and much more.

Automate Python package releases

I maintain a handful of Python packages. Here's how I automate creating new releases, both on PyPI and GitHub.

Why Django's DATETIME_FORMAT ignores you (and how to fix it)

A dive into why Django's DATETIME_FORMAT setting seems to do nothing, and how to actually force the 24-hour clock in the admin, even when your locale says otherwise.

Django at 20: a personal journey through 16 years

Celebrating Django's 20th birthday by looking back at 16 years of personal Django usage, how it evolved, favorite packages, and what I'd love to see in the future.

Handling static and media files in your Django app running on Coolify

Let's solve the challenge of serving media files for your Coolified Django site.

I code in my dreams

I often get my best coding inspiration late at night, and when I go to bed with an unsolved problem, I literally write lines of code in my dreams.

Hosting your Django sites with Coolify

How I moved my Django projects from a manual server setup to Coolify for easier, zero-downtime deployments.

Production-ready cache-busting for Django and Tailwind CSS

I'm a big fan of the django-tailwind-cli package, but I ran into problems deploying it to production. Here's how to make sure you cache-bust tailwind.css.

Liquid Disappointment

Yesterday I installed the iOS 26 beta on my iPhone and today, for the first time ever, I've downgraded my iPhone back to the stable release.

A tale of three type systems: Python, TypeScript, and Swift

I recently ported Saga from Swift to both Python and TypeScript. It was a fascinating exercise in cognitive dissonance, especially when it came to their type systems.

Garbage in, garbage out: why good developers are still necessary in the age of LLMs

Luckily for us, good developers are still necessary in the age of LLMs. You can't just say "make an app", you still need to know how to build a good app.

Make Django show dates and times in the visitor's local timezone

A robust, two-part solution for showing dates and times in your visitor's local timezone, handling the tricky first-visit problem.