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.
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.
Saga 3 brings much faster builds and a more flexible pipeline, while Parsley 1.2 adds powerful Markdown attribute support.
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.
As I prepare Saga 3, I keep running into fundamental limitations in Swift Package Manager that make maintaining a plugin ecosystem unnecessarily painful.
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.
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.
A collection of reusable utilities for Saga, extracted from this very website: composable HTML transformations and useful String extensions.
I've created a new HTML minifier in pure Swift, with zero dependencies and performance on par with the best Node.js minifiers.
How I used Cloudflare's free security rules to filter bot traffic from my self-hosted Umami analytics.
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.
After years on Plausible I switched to self-hosting and discovered just how much they hold back from their open source version.
This is the stuff I use daily for development, photography, and gaming.
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.
If your Coolify deployments are sometimes fast and sometimes mysteriously slow, Docker's BuildKit garbage collection is probably silently deleting your build cache.
I built the same site with Hugo, Publish, and Saga to compare how each static site generator handles real-world requirements.
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.
The company I once admired has become morally bankrupt, but leaving the ecosystem feels almost impossible.
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.
I've created a new Swift package that does server-side syntax highlighting of HTML content, using Prism.js.
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.
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.
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.
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.
Let's get into personal stuff, freelance work, and open source projects.
How to run schema-changing Django migrations safely, avoiding schema/code mismatches and server errors during rolling deploys.
A deep dive into Docker layer caching, BuildKit cache mounts, and how a Coolify bug can sabotage your build times, plus what you can (and can't) do about it.
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.
What if the secret to a thriving side project isn't more expertise, but less overlap with your day job?
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.
Did you know that you can run unit tests for your Django app, in GitHub Actions, using PostgreSQL?
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's generic class-based views often clash with the Zen of Python. Here's why the base View class feels more Pythonic.
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 reflection on 25 years of web development, from simplicity to complexity and back.
Why I only use Django's base View class instead of generic class-based views or function-based views.
A modern, flexible rewrite of django-generic-notifications is here. Easily send website and email notifications, create digests, group similar messages, and much more.
I maintain a handful of Python packages. Here's how I automate creating new releases, both on PyPI and GitHub.
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.
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.
Let's solve the challenge of serving media files for your Coolified Django site.
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.
How I moved my Django projects from a manual server setup to Coolify for easier, zero-downtime deployments.
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.
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.
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.
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.
A robust, two-part solution for showing dates and times in your visitor's local timezone, handling the tricky first-visit problem.
Ditch the complex SPA. Learn how to build modern, server-rendered Django apps using Alpine AJAX and the power of hypermedia.
After more than a decade of iOS development, the company's anti-developer stance, Swift's growing complexity, and the eroding software quality led me back to the open web.
An easy way to use different serializers for different actions and request methods in Django REST Framework.
Webservers get hit by hundreds of thousands of requests to random (non-existing) PHP files. Let's block it using CloudFlare's WAF rules.
Many people quickly reach for a big CMS package for Django, when often this is overkill. Here's how to use a simple Django model with a CKEditor 5 WYSIWYG field.
I love RSS feeds, but it's not ideal that you're stuck with all the articles that are in the feed. So I built RSSfilter.com, offering a way to filter the feed based on keywords and categories.
When you have admin users in multiple time zones, the way Django handles the input and display of dates and times is causing confusion. Here's how you can improve things.
It's been three months since I migrated all my Python projects over to uv. And it's only gotten better! Let's look at two recent major improvements.
Apple's DocC project and the Swift Package Manager have been missing pretty crucial features for years now. It's time that Apple gave them some love and attention.
What would Saga look like if it were written in Python or TypeScript, rather than in Swift? Is it worth the effort to port Saga to another language?
I started building Saga, my own static site generator written in Swift, four years ago. Let's look at the state of the project.
I use django-apscheduler to run a queue of scheduled tasks. Now I also need the ability to run one-off tasks and that turned out to not be so simple.
One pattern that I love to use in my SvelteKit projects is returning writable stores from the layout's load function. Can we migrate this to the new $state rune?
I'm migrating a big SvelteKit project to Svelte 5's new runes syntax and I have to be honest: not a big fan of the increased number of lines, especially when it comes to the props.
It's time to look back and see what has changed and what has stayed the same.
I started using Django in 2009, and fifteen years later I am still a happy user. It's clear that Django is rather special.
Quite recently I upgraded a Svelte 4 project to Svelte 5, and soon afterwards I found some problems inside of Safari 12 and 13 that needed a tricky workaround.
So, like me you've decided to switch from Poetry to uv, and now you're wondering how to actually migrate your pyproject.toml file? You've come to the right place!
Solving problems by putting writable reactive stores in Svelte's context.
Two months ago I compared Poetry with uv, and for me uv had significant drawbacks that kept me from switching over. The situation has changed quite a bit since then!
I wanted to use a different MEDIA_URL for one of our FileField instances. It was very easy to do!
Let's compare Django REST Framework with new kid on the block, Ninja.
The best feature of Heroku is the ability to just push a branch, and it gets deployed. How do we replicate a workflow like that on our own server?
After comparing uv to Poetry, I am trying out PDM. On paper it combines all the best things of Poetry and uv, without their downsides. How does it hold up?
There are many ways to configure Django, like multiple settings files or .env files. Here's how I do it, using python-dotenv.
Paypal's documentation only shows a JavaScript example. How do you validate the webhooks in Python though?
I've added a comment section to the articles, powered by GitHub Discussions.
Comparing two Python package managers: Poetry and new kid on the block uv.
Django 5.1 adds related field lookup to the model admin's list_display, but with an annoying quirk. Let's fix that!
Extending Django's autocomplete widget with a new action which copies the linked user's email address to the clipboard.
How do you update content in real time when that content was fetched from the layout's load function?
Webservers get hit by hundreds of thousands of requests to random (non-existing) PHP files. Let's block them using UFW and fail2ban.
I bought the 12.9" iPad Pro with the Apple Pencil back in 2018 and spoiler alert: I still use the iPad almost every day.
I rented a Tesla model 3 in Iceland, and let's just say I have some opinions.
Time flies, and it's flying faster and faster each and every year.
How do you delete baskets belonging to anonymous users when their sessions expire? It wasn't quite as simple as I thought.
Let's add custom actions to Django's admin site - but to the change form, not the list view.
A complete how-to guide for setting up Debian from scratch, for SvelteKit and Django.
2022 was very busy and somewhat stressful year - although not for all the reasons I predicted a year ago.
SvelteKit version 1.0.0-next.415 removed the session object and store. Refactoring my project wasn't very straightforward, let's go over the changes.
Last August I wrote about trying to come up with the architecture for a SvelteKit app I was working on, and failing. I'm happy to say that I have found a solution for all my problems!
Another year of not going abroad, barely seeing friends, playing Dungeons & Dragons via Zoom instead of at the table. But also a year of hope.
When HttpOnly cookies didn't work as expected in my SvelteKit project I had to find a workaround.
It's taken a little bit longer than I expected, but 1.0.0 has finally been released, with support for async readers and item processing functions.
Over two years ago I wrote an article where I compared Vapor 3 to Django REST Framework. It's time for a rematch with Vapor 4.
Trying to architect a SvelteKit app so that it does as few requests as possible, from a central place, so that all subpages have access to the content.
I'm trying out Vapor 4 for a side project, and one thing that I am constantly running into is the amount of boilerplate and copy-pasted code. Are there no better solutions for this?
Recently I was interviewed for the Russian IT website proglib.io. Since it might be interesting for non-Russian speakers, here it is in the original English version.
One of my mentees asked about the coordinator pattern: how to implement it, and what the big deal is about decoupling view controllers.
It's a question I asked myself too, when I just got started with Combine.
In JavaScript-world, it's really easy to know when multiple promises completed: just use Promise.all. How do you do the same thing in Combine?
I've released a GitHub Action that automatically generates a changelog when you push a tag.
Comparing Parsley to Ink, Down, and MarkdownKit.
In the past few days I've made some pretty substantial improvements to Saga, to make it work for me and my website, which is now built using Saga.
I've already replaced my own SwiftMarkdown package...
I've replaced the Ink and Splash dependencies with my own SwiftMarkdown package.
An unexpectedly quick fourth article about Saga, after a complete redesign of the API.
In the third and final part of this series about Saga I'm looking at the pros and cons of the current system and what I might want to change.
Part 2, where I'm looking back at the current API of Saga.
In part 1 of a series of articles I'm looking at the inspiration behind my static site generator Saga, now available on Github.
Working with generics in Swift becomes a headache when you want to put things in an array. Am I stuck with type erasure and type casting?
I'm taking a look at the static site generator Publish, written in Swift.
Resources for learning Swift and UIKit, what to build first, opinions on Unit Testing, and more.
My take on the very common question "What should I learn or focus on? UIKit or SwiftUI?"
A while ago I asked on Twitter which Swift-related book I should review next, and overwhelmingly Thinking in SwiftUI by the objc.io guys was chosen. An excellent choice!
SwiftUI's @Binding property wrapper makes it easy to create two-way databindings, but in the UIKit world it's slightly less easy. Let's explore some solutions.
Great book, and well worth the $25.
Since it was a bit of a puzzle to get it working, I am sharing my backend and frontend code.
I've been working with SwiftUI for almost half a year now I love a lot about it, but there are also so many bugs and issues that need workarounds that it's kind of maddening.
Comparing Stripe, Gumroad, Patreon, and Memberstack.
I've recently added subscriptions to my Critical Notes iOS app, using Apple's StoreKit. Here is how I hooked it all up to Firestore including server-side receipt validation.
When you delete a document in Firestore, its subcollections and their documents are not automatically recursively deleted. Here is a simple Cloud Function that takes care of it.
I couldn't choose between Vapor and Django, and went with a third option.