<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>jotaen.net</title>
    <link>https://www.jotaen.net</link>
    <description>Jan Heuermann’s blog</description>
    <language>en-gb</language>
    <copyright>Jan Heuermann</copyright>
    <lastBuildDate>Fri, 21 Aug 2026 00:00:00 +0000</lastBuildDate>
      <atom:link href="https://www.jotaen.net/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Let’s talk about “vibe writing”</title>
      <guid isPermaLink="true">https://www.jotaen.net/23sHT</guid>
      <link>https://www.jotaen.net/23sHT</link>
      <pubDate>Fri, 21 Aug 2026 00:00:00 +0000</pubDate>
      <description>When it comes to writing, I only used AI for smaller requests for a long time: fixing a typo, or smoothing over a clumsy sentence – the sort of thing a spellchecker does. I always found that handy, especially in English, which isn’t my mother tongue, but it never struck me as anything more than that.&#xA;On a whim, one day I pasted a rough draft of a technical document into the LLM – mostly bullet points and a few half-finished sentences – and asked it for feedback.</description>
    </item>
    
    <item>
      <title>Timer – Programmable timer web app – e.g. for gym workouts or stretching sessions</title>
      <guid isPermaLink="true">https://www.jotaen.net/SAKxq</guid>
      <link>https://www.jotaen.net/SAKxq</link>
      <pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate>
      <description>I have a mild habit of building my own version of things that surely already exist. This time it’s a timer web app – one that counts down, beeps, and reads activity names out loud. The main use-case is workout or stretching sessions that consist of repeatable sequences, e.g. where you are holding certain positions for a set time. The neat part is that the timers are “programmable”, so you can create your own routines and structure them freely.</description>
    </item>
    
    <item>
      <title>Ali Baba and the Forty Relying Parties – A tale from 1001 Nights, but with passkeys</title>
      <guid isPermaLink="true">https://www.jotaen.net/G3zzX</guid>
      <link>https://www.jotaen.net/G3zzX</link>
      <pubDate>Thu, 23 Jul 2026 00:00:00 +0000</pubDate>
      <description>This blog post is a silly adaptation of the tale of “Ali Baba and the Forty Thieves” and tells it as if the equivalent of passkeys were used instead of the (rather insecure) password “open sesame”.&#xA;I. The Word The thieves kept their cave shut with a word, and the word was “sesame”.&#xA;Behind the door they piled what they took off the caravan roads, which over the years amounted to a great deal: bolts of stiff Damascus silk, saffron in stoppered jars, coin from mints nobody in the district could name, and loose gold enough to founder a camel.</description>
    </item>
    
    <item>
      <title>How to write great PR descriptions</title>
      <guid isPermaLink="true">https://www.jotaen.net/qDrr1</guid>
      <link>https://www.jotaen.net/qDrr1</link>
      <pubDate>Thu, 09 Jul 2026 00:00:00 +0000</pubDate>
      <description>Have you ever reviewed a pull request (PR) with a diff of a few hundred lines of code, for which the PR description merely said something like: “Add CSV export for messages”?&#xA;I believe that a good PR description serves two main purposes: it documents a change for current and future reference, and it facilitates a swift and frictionless review process.&#xA;What I find important to appreciate is that there is an asymmetry between creator and reader of a PR.</description>
    </item>
    
    <item>
      <title>3 gripes about Go modules – (Number 4 will drive you crazy)</title>
      <guid isPermaLink="true">https://www.jotaen.net/e3Jq5</guid>
      <link>https://www.jotaen.net/e3Jq5</link>
      <pubDate>Fri, 10 Oct 2025 00:00:00 +0000</pubDate>
      <description>Do you remember $GOPATH? It’s from the era before Go modules came to be, where installing Go libraries used to be a manual, rather frustrating experience. (This also isn’t that long ago, actually.)&#xA;Say what you will about Go modules, but compared to the $GOPATH times, they have been a literal godsend: installing, publishing, and finding packages has since become a standardised and convenient process.&#xA;So there really shouldn&amp;rsquo;t be anything to complain about.</description>
    </item>
    
    <item>
      <title>Fun with overflowing integers</title>
      <guid isPermaLink="true">https://www.jotaen.net/YNkLs</guid>
      <link>https://www.jotaen.net/YNkLs</link>
      <pubDate>Fri, 14 Feb 2025 00:00:00 +0000</pubDate>
      <description>Today, I finally got around to fixing a fundamental issue with klog (my command line tool for time tracking): if someone were to use klog on a daily basis for a few trillion years, there would be an increased risk of incorrect computations due to integer overflow.&#xA;In particular, after precisely 9223372036854775807 minutes worth of time tracking, the total time amount would wrap around and continue at -9223372036854775808 minutes. I wouldn’t go as far to call this a time bomb ticking right there, but you know, time is money, and that’s where things get serious (especially in this ballpark).</description>
    </item>
    
    <item>
      <title>Not all binary state is boolean</title>
      <guid isPermaLink="true">https://www.jotaen.net/HI4Ck</guid>
      <link>https://www.jotaen.net/HI4Ck</link>
      <pubDate>Sat, 07 Dec 2024 00:00:00 +0000</pubDate>
      <description>Boolean types represent binary state: true↔false, 1↔0, on↔off.&#xA;But just because boolean types are technically capable of expressing binary state, they may not always be an ideal choice from a semantic point of view.&#xA;Consider the following Java interface, which describes the view state of a graphical user interface by means of two boolean methods:&#xA;interface UserInterface { boolean hasFocus(); boolean isDarkModeEnabled(); } In my book, a boolean type would be an appropriate choice for hasFocus().</description>
    </item>
    
    <item>
      <title>Custom git subcommands</title>
      <guid isPermaLink="true">https://www.jotaen.net/1Uvns</guid>
      <link>https://www.jotaen.net/1Uvns</link>
      <pubDate>Sat, 30 Nov 2024 00:00:00 +0000</pubDate>
      <description>There are two ways to register custom subcommands for the git CLI tool. That allows you to define your own shortcuts and invoke them as if they were natively supported by git. For example, just like the built-in subcommands such as git checkout or git diff, you could come up with git mycrazycommand and define custom behaviour for it.&#xA;The following sections demonstrate two possible techniques to define a custom subcommand: aliases (1) and dedicated shell scripts (2).</description>
    </item>
    
    <item>
      <title>Shortcut for “docker run”</title>
      <guid isPermaLink="true">https://www.jotaen.net/YbKvZ</guid>
      <link>https://www.jotaen.net/YbKvZ</link>
      <pubDate>Wed, 16 Oct 2024 00:00:00 +0000</pubDate>
      <description>Docker is one of my daily drivers in my local development toolchain. I mostly rely on it for spawning dedicated development environments, which are tailored to the specific project I’m working on.&#xA;I usually add a Dockerfile or docker-compose.yml file rather early to my projects. (Independent of whether I actually use Docker in production.) However, for initial prototyping, or for just briefly trying something in an ad-hoc manner, I created a small shortcut that I find quite handy.</description>
    </item>
    
    <item>
      <title>Keep track of migration state in SQlite</title>
      <guid isPermaLink="true">https://www.jotaen.net/c54IG</guid>
      <link>https://www.jotaen.net/c54IG</link>
      <pubDate>Tue, 03 Sep 2024 00:00:00 +0000</pubDate>
      <description>Keeping track of database migrations in SQlite DB files can generally be done in the same way as with any other database. The most common approach is to provide a separate database table for maintaining the history of all migrations that have already been applied.&#xA;In SQlite, there is a more subtle alternative to this, which is to use the user_version PRAGMA:&#xA;The user-version is an integer that is available to applications to use however they want.</description>
    </item>
    
    <item>
      <title>Inlining images in HTML</title>
      <guid isPermaLink="true">https://www.jotaen.net/KWGql</guid>
      <link>https://www.jotaen.net/KWGql</link>
      <pubDate>Wed, 24 Jul 2024 00:00:00 +0000</pubDate>
      <description>When using small icons on a web page, it sometimes can be convenient to embed the respective image into the HTML code directly, instead of providing it as static image file and then fetching it via its URL in a separate HTTP request.&#xA;For example, the following klog logo isn’t hosted as separate image file on the web server, but the image data is directly included in the HTML code. This can be achieved by using data URLs and a base64-encoded image blob.</description>
    </item>
    
    <item>
      <title>Testing HTTP APIs with hurl</title>
      <guid isPermaLink="true">https://www.jotaen.net/nzDuh</guid>
      <link>https://www.jotaen.net/nzDuh</link>
      <pubDate>Sun, 07 Jul 2024 00:00:00 +0000</pubDate>
      <description>hurl is a command line tool for running HTTP requests. The clue is that the definitions of the HTTP requests are stored in plain text files, and that the CLI tool has some useful capabilities around working with HTTP requests and the corresponding responses. That allows for two main usages of the tool:&#xA;Maintaining an internal library of API calls for manual testing during development. Think Postman, but backed by plain text files and a CLI tool.</description>
    </item>
    
    <item>
      <title>Immediately invoked function expressions</title>
      <guid isPermaLink="true">https://www.jotaen.net/DWZaD</guid>
      <link>https://www.jotaen.net/DWZaD</link>
      <pubDate>Thu, 09 May 2024 00:00:00 +0000</pubDate>
      <description>IIFEs (immediately invoked function expressions) are a neat code pattern originally popularised by JavaScript, which, however, seem to be less common of in other languages.&#xA;An IIFE is basically an inlined function expression that is executed right away. You can use this technique not just in JavaScript, but in all languages where functions are first-class citizens.1&#xA;const theAnswer = (() =&amp;gt; { return 42; })(); In JavaScript, the syntax recipe is:</description>
    </item>
    
    <item>
      <title>Happy Anniversary! – Looking back on 10 years of blogging</title>
      <guid isPermaLink="true">https://www.jotaen.net/3tyCJ</guid>
      <link>https://www.jotaen.net/3tyCJ</link>
      <pubDate>Wed, 21 Feb 2024 00:00:00 +0000</pubDate>
      <description>10 years ago to the day, on 21st February 2014, I published my first article on this blog.&#xA;This anniversary feels special to me, because I’ve been running my blog for almost my entire career now. So looking back on how this website evolved throughout the years actually makes me realise the various ways in which things are linked to my professional journey.&#xA;Before this post turns into some sort of therapy session, however, I’d rather like to use the opportunity to reflect a bit on blogging itself: I cobbled together some statistics I did some sophisticated data-driven analysis, pondered on why the hell I’m doing all this elaborated on my motives and incentives, and advertised a few random articles to drive engagement and carefully hand-picked a few articles from the archive that I’d consider notable.</description>
    </item>
    
    <item>
      <title>snapdiff – CLI tool, written in Rust, to analyse the difference between two directory snapshots</title>
      <guid isPermaLink="true">https://www.jotaen.net/iE3XC</guid>
      <link>https://www.jotaen.net/iE3XC</link>
      <pubDate>Mon, 22 Jan 2024 00:00:00 +0000</pubDate>
      <description>I periodically create snapshots of large directory trees for backup purposes. The snapshotting procedure is basically cp -R, so each snapshot is a full copy of the directory tree in question.&#xA;I archive these snapshots either on my internal disk or on an external one. In any event, I end up with a whole bunch of snapshots – all representing the same directory tree, but at different points in time.</description>
    </item>
    
    <item>
      <title>Let’s self-host! – Get started with self-hosting, using Docker, HAProxy and Let’s Encrypt</title>
      <guid isPermaLink="true">https://www.jotaen.net/anA6o</guid>
      <link>https://www.jotaen.net/anA6o</link>
      <pubDate>Tue, 28 Nov 2023 00:00:00 +0000</pubDate>
      <description>Self-hosting is a fun and cost-efficient way to run web services, be it for some silly side-projects, or for miscellaneous third-party services that you want to host for personal usage.&#xA;Unless you are motivated to operate a physical machine off your own basement, the easiest option is to rent a (virtual) server at some hosting provider of your choice – say, Hetzner, DigitalOcean, or Your-Friendly-Data-Center-From-Around-The-Corner™. For a few bucks a month, you get root access, decent computing power, and plenty of disk space to mess around with.</description>
    </item>
    
    <item>
      <title>“Congrats!” – The future of AI-enhanced online networking for professionals</title>
      <guid isPermaLink="true">https://www.jotaen.net/upfqo</guid>
      <link>https://www.jotaen.net/upfqo</link>
      <pubDate>Thu, 03 Aug 2023 00:00:00 +0000</pubDate>
      <description>I love LinkedIn. I would even go as far to say: I am a downright LinkedIn maniac. I log into LinkedIn multiple times a day, to stay on top of what’s happening in my business network, and to engage in meaningful interactions with other professionals around the globe.&#xA;After logging in, LinkedIn displays a dashboard with an activity feed, where it summarises all the latest occurrences that are relevant in my network.</description>
    </item>
    
    <item>
      <title>fail err – Musings about error handling syntax in Go (2/2)</title>
      <guid isPermaLink="true">https://www.jotaen.net/thcRw</guid>
      <link>https://www.jotaen.net/thcRw</link>
      <pubDate>Sun, 12 Mar 2023 00:00:00 +0000</pubDate>
      <description>Warning: the following post explores crazy ideas around error handling syntax in the Go programming language. Unlike normally on my blog, it’s considered okay to stop reading this post at any point. If you are sensitive to thought experiments around language design in Go, you are advised to take preliminary measures to leave this page promptly in case you feel sudden discomfort.&#xA;In a previous blog post, I discussed an idea for a dedicated error handling syntax for the Go programming language.</description>
    </item>
    
    <item>
      <title>The fallacy of software development principles – Why SOLID, TDD, or Clean Code won’t make us good programmers</title>
      <guid isPermaLink="true">https://www.jotaen.net/aXSeX</guid>
      <link>https://www.jotaen.net/aXSeX</link>
      <pubDate>Sun, 19 Feb 2023 00:00:00 +0000</pubDate>
      <description>What is good code? To research this question, imagine we put 100 software developers into one room, give them 10 code bases to evaluate, and ask them to create a ranking based on code quality. In reality, this will probably take a good while, and also have significant risk of domestic violence. But since this is just a thought experiment, we can assume that it all goes smooth and civilised. While the eventual survey result would certainly not be unanimous, it’s still likely that there will be an overall trend that the majority of participants can agree on.</description>
    </item>
    
    <item>
      <title>On “free” and “open-source” software – How language makes the people, and people make the language</title>
      <guid isPermaLink="true">https://www.jotaen.net/8LgpO</guid>
      <link>https://www.jotaen.net/8LgpO</link>
      <pubDate>Mon, 30 Jan 2023 00:00:00 +0000</pubDate>
      <description>Did you know that computers existed way before the mid 20th century? The first record of a computer dates back as early as 1613, and there is evidence that computers have been known and routinely utilised throughout the following centuries. Their probably most important field of application was for carrying out calculations in the context of astronomic research. (At times, a controversial and even somewhat delicate undertaking, however.)&#xA;Even though the computers of back then weren’t nearly as powerful as the ones we have today, some of them had remarkable capabilities.</description>
    </item>
    
  </channel>
</rss>
