<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Michiel's Blog</title><link href="https://tildeweb.nl/~michiel/" rel="alternate"/><link href="https://tildeweb.nl/~michiel/atom.xml" rel="self"/><id>https://tildeweb.nl/~michiel/</id><updated>2026-05-03T22:00:00+02:00</updated><subtitle>Blog</subtitle><entry><title>Talk at PyGrunn on httpxyz</title><link href="https://tildeweb.nl/~michiel/pygrunn-httpxyz.html" rel="alternate"/><published>2026-05-03T22:00:00+02:00</published><updated>2026-05-03T22:00:00+02:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-05-03:/~michiel/pygrunn-httpxyz.html</id><summary type="html">I'm giving yet another talk on our new Python package httpxyz!</summary><content type="html">&lt;p&gt;On Friday 8th of May 2026 I will be giving a talk on our new fork of the
popular python package &lt;strong&gt;httpx&lt;/strong&gt; called &lt;a href="https://httpxyz.org"&gt;httpxyz&lt;/a&gt; at
&lt;a href="https://pygrunn.org"&gt;PyGrunn&lt;/a&gt;. &lt;strong&gt;PyGrunn&lt;/strong&gt; is a full day Python (&amp;ldquo;and
friends&amp;rdquo;) conference in Groningen, The Netherlands. &lt;strong&gt;httpx&lt;/strong&gt; is a top-100
Python package for sending http requests but has not had a release since end of
2024, plus, recently all issues were set to hidden and all discussions are
closed. &lt;strong&gt;httpxyz&lt;/strong&gt; is our friendly fork with lots of fixes for serious and
more niche issues. Read for more info my
&lt;a href="httpxyz.html"&gt;announcement post for httpxyz&lt;/a&gt;. I will talk about why we did the
fork and how we approach it. I&amp;rsquo;ll also delve into how to build a performant API
client in Python and technical details of HTTP.&lt;/p&gt;
&lt;p&gt;This is an expanded version of the talk I gave at
&lt;a href="pyamsterdam-httpxyz.html"&gt;PyAmsterdam&lt;/a&gt; last week, and is part of my &amp;lsquo;promotion
efforts&amp;rsquo; for &lt;a href="https://httpxyz.org"&gt;httpxyz&lt;/a&gt;. I look forward to giving my talk &amp;amp;
see you there!&lt;/p&gt;
&lt;p&gt;&lt;img alt="Me presenting at PyAmsterdam" class="small" src="images/mwb-zstandard.jpg"&gt;&lt;/p&gt;</content></entry><entry><title>httpxyz one month in</title><link href="https://tildeweb.nl/~michiel/httpxyz-one-month-in.html" rel="alternate"/><published>2026-04-27T09:00:00+02:00</published><updated>2026-04-27T09:00:00+02:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-04-27:/~michiel/httpxyz-one-month-in.html</id><summary type="html">One month after forking httpxyz, where we are now and where we're going</summary><content type="html">&lt;p&gt;It has been roughly a month since we forked
&lt;a href="https://github.com/encode/httpx"&gt;httpx&lt;/a&gt; and named our package
&lt;a href="https://httpxyz.org"&gt;httpxyz&lt;/a&gt;. For the reasons why I refer you to
&lt;a href="httpxyz.html"&gt;Why I forked httpx&lt;/a&gt;. In this post I will explain where we are
now, one month &amp;lsquo;into&amp;rsquo; having created the fork.&lt;/p&gt;
&lt;p&gt;TL;DR: httpxyz has now many bug fixes and significantly better performance than
httpx, and we would encourage anyone to move to our version!&lt;/p&gt;
&lt;p&gt;&lt;img alt="httpxyz logo" src="images/httpxyz.png"&gt;&lt;/p&gt;
&lt;h2&gt;Where we are now&lt;/h2&gt;
&lt;h3&gt;Initial version of fork&lt;/h3&gt;
&lt;p&gt;Our first version of httpxyz contained just the fixes to get zstd working, and
the fixes to get the test suite running on python 3.14, some &amp;lsquo;housekeeping&amp;rsquo;
changes related to the renaming, as well as some minor and trivial fixes that
had already been merged in httpx and had not been released yet.&lt;/p&gt;
&lt;h3&gt;End of March: bugfixes, and performance improvements&lt;/h3&gt;
&lt;p&gt;Then at the end of March we did another release of httpxyz, containing a
compatibility shim that allows you to use httpxyz even with third-party
packages that import httpx themselves, as long as you import httpxyz first.
We&amp;rsquo;ve added a nice
&lt;a href="https://httpxyz.org/httpx-compatibility/"&gt;documentation page&lt;/a&gt; for this.&lt;/p&gt;
&lt;p&gt;This release also included a change that lazily imports the CLI for httpxyz,
which is typically not used in your app; in my measurements this makes httpxyz
import in &lt;em&gt;half&lt;/em&gt; the time needed by httpx. This PR has been sitting idle at the
httpx repository for over a year
&lt;a href="https://github.com/encode/httpx/pull/3547"&gt;ref&lt;/a&gt; and we&amp;rsquo;ve kindly adopted it,
thanks to &lt;a href="https://github.com/natehardison"&gt;Nate Hardison&lt;/a&gt; for providing it!&lt;/p&gt;
&lt;p&gt;And apart from that we adopted a bunch of other smaller and bigger bug fixes
and improvements in this release.&lt;/p&gt;
&lt;h3&gt;httpcorexyz!&lt;/h3&gt;
&lt;p&gt;But we realized pretty soon that there were some problems that httpx was
having, that were actually caused by the underlying &amp;lsquo;transport&amp;rsquo; which is
defined in a different module, &lt;a href="https://github.com/encode/httpcore"&gt;httpcore&lt;/a&gt;.
This module also had no release in over a year, and there were a bunch of
issues reported by users, with fixes even, that were not landing. So we ended
up also forking httpcore and created
&lt;a href="https://httpxyz.org/httpcorexyz/"&gt;httpcorexyz&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here we fixed a WHOLE bunch of performance related issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;anyio.Lock(fast_acquire=True)&lt;/code&gt; and &lt;code&gt;anyio.Semaphore(fast_acquire=True)&lt;/code&gt;
  to skip unnecessary event loop yields on uncontended lock acquires. Reduces
  async GET latency by ~3.3x. Reinstates encode/httpcore#953 which was reverted
  upstream for non-technical reasons. Requires anyio &amp;gt;= 4.5.0.
  &lt;a href="https://codeberg.org/httpxyz/httpcorexyz/commit/4a4eb1eff2594af449cbc4168e63385c2638a3d2"&gt;ref&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Retire &lt;code&gt;map_exceptions()&lt;/code&gt; context manager in favour of plain &lt;code&gt;try/except&lt;/code&gt; on
  hot paths (socket reads, writes, connects). &lt;code&gt;try/except&lt;/code&gt; with no exception is
  nearly free; &lt;code&gt;@contextmanager&lt;/code&gt;-based &lt;code&gt;with&lt;/code&gt; blocks have measurable overhead.
  (encode/httpcore#1044)
  &lt;a href="https://codeberg.org/httpxyz/httpcorexyz/pulls/14"&gt;PR 14&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Make &lt;code&gt;Origin&lt;/code&gt; hashable via &lt;code&gt;Origin.__hash__()&lt;/code&gt; for use in sets and dicts.
  (encode/httpcore#1038)&lt;/li&gt;
&lt;li&gt;Release the HTTP/2 max-streams semaphore and decrement &lt;code&gt;_concurrent_streams&lt;/code&gt;
  when &lt;code&gt;NoAvailableStreamIDError&lt;/code&gt; is raised, preventing permanent deadlock.
  (encode/httpcore#1061)
  &lt;a href="https://codeberg.org/httpxyz/httpcorexyz/pulls/10"&gt;PR 10&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Move &lt;code&gt;del self._events[stream_id]&lt;/code&gt; inside the &lt;code&gt;_state_lock&lt;/code&gt; in
  &lt;code&gt;_response_closed()&lt;/code&gt; to prevent a race condition with concurrent coroutines.
  (encode/httpcore#1062)&lt;/li&gt;
&lt;li&gt;Close proxy connection when tunnel TLS handshake fails, preventing the pool
  from stalling at &lt;code&gt;max_connections&lt;/code&gt;. (encode/httpcore#1049)&lt;/li&gt;
&lt;li&gt;Propagate the connect timeout through the SOCKS5 handshake to prevent
  indefinite hangs with non-responsive proxies. (encode/httpcore#1055)
  &lt;a href="https://codeberg.org/httpxyz/httpcorexyz/commit/038793021a14e70039c62137c2a9bd16627adfa4"&gt;ref&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Explicitly close async generators via &lt;code&gt;safe_async_iterate()&lt;/code&gt; context managers
  to prevent Trio warnings and unpredictable GC-dependent behaviour.
  (encode/httpcore#1019)
  &lt;a href="https://codeberg.org/httpxyz/httpcorexyz/commit/c4e9340375836a5202b946e18e8de98c3d1f8846"&gt;ref&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Reduce lock contention in &lt;code&gt;PoolByteStream.close()&lt;/code&gt;: pool requests are marked
  as closed outside the lock and cleaned up lazily inside
  &lt;code&gt;_assign_requests_to_connections()&lt;/code&gt;. (encode/httpcore#1038)
  &lt;a href="https://codeberg.org/httpxyz/httpcorexyz/commit/9d86b4472dadc6c8d6dfebdc988922378081a713"&gt;ref&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are serious issues, and it&amp;rsquo;s not even all. Almost all of these were
already fixed by &amp;lsquo;the community&amp;rsquo; and were living in unmerged pull requests. We
code reviewed them, fixed them up where needed and adapted them to our code
base. We also now added a
&lt;a href="https://codeberg.org/httpxyz/httpcorexyz/src/branch/main/docs/benchmarks.md"&gt;benchmarks&lt;/a&gt;
section to the documentation; httpxyz is now MUCH faster than httpx in many
serious use cases.&lt;/p&gt;
&lt;p&gt;Then we released a new version of HTTPXYZ earlier this week:
&lt;a href="https://codeberg.org/httpxyz/httpxyz/src/branch/main/CHANGELOG.md#0-31-0-25th-april-2026-now-on-httpcorexyz-with-major-performance-improvements"&gt;0.31.0&lt;/a&gt;
with this updated version of httpcorexyz and also more bug fixes of its own.&lt;/p&gt;
&lt;p&gt;Where I previously stated having the fork is about future-proofing and I would
not necessarily recommend people to switch to httpx, with this new version
0.31.0 I now feel that you should definitely move to httpxyz. With All new
fixes and performance improvements it now makes &amp;lsquo;business sense&amp;rsquo; to switch from
httpx to httpxyz, the &amp;lsquo;churn&amp;rsquo; is worth it now!&lt;/p&gt;
&lt;h2&gt;Adoption&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;re happy to see projects moving to using our package, even though it&amp;rsquo;s not
much yet. We encourage everyone to do so, and please tell others and convince
them! If you would find issues with your switchover, which I do not expect,
please just open &lt;a href="https://codeberg.org/httpxyz/httpxyz/issues"&gt;an issue&lt;/a&gt; and
I&amp;rsquo;m sure we can figure it out!&lt;/p&gt;
&lt;h2&gt;Quotes&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;I'm a big user of httpx... Thanks for the fork. Here's to hoping it gained some traction. (Michael Kennedy, Founder, Talk Python)&lt;/p&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;p&gt;Thank you for forking httpx. httpx is a joy to work with, but clearly a bit dead in the water. Really nice to see it moving forward again. (hhartzer)&lt;/p&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;p&gt;If you want to have traction, you should probably move to GitHub instead of using Codeberg (Marcelo Trylesinski aka Kludex / FastAPI)&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;On Codeberg&lt;/h2&gt;
&lt;p&gt;We explained &lt;a href="httpxyz.html"&gt;the last time&lt;/a&gt; why we chose Codeberg; we&amp;rsquo;re not
unhappy about our choice. We got 39 &amp;lsquo;stars&amp;rsquo; so far on our
&lt;a href="https://codeberg.org/httpxyz/httpxyz"&gt;Codeberg repository&lt;/a&gt; and many of those
are from &amp;lsquo;fresh&amp;rsquo; accounts. If us being on codeberg helps a tiny little bit
making github a bit less dominant, I think this is a good thing, and I hope it
can inspire other projects to do the same. And after all, for most users, who
would just &lt;code&gt;pip install httpxyz&lt;/code&gt; or &lt;code&gt;uv add httpxyz&lt;/code&gt; it does not matter where
the source is hosted.&lt;/p&gt;
&lt;p&gt;Thanks, and have fun!&lt;/p&gt;</content></entry><entry><title>Talk at PyAmsterdam on httpxyz</title><link href="https://tildeweb.nl/~michiel/pyamsterdam-httpxyz.html" rel="alternate"/><published>2026-04-21T22:00:00+02:00</published><updated>2026-04-21T22:00:00+02:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-04-21:/~michiel/pyamsterdam-httpxyz.html</id><summary type="html">I'm giving a lightning talk on our new Python package httpxyz!</summary><content type="html">&lt;p&gt;On Wednesday 29th of April 2026 I will be giving a lightning talk on our new
fork of the popular python package &lt;strong&gt;httpx&lt;/strong&gt; called
&lt;a href="https://httpxyz.org"&gt;httpxyz&lt;/a&gt; at PyAmsterdam. &lt;strong&gt;httpx&lt;/strong&gt; is a top-100 Python
package for sending http requests but has not had a release since end of 2024,
plus, recently all issues were set to hidden and all discussions are closed.
&lt;strong&gt;httpxyz&lt;/strong&gt; is our friendly fork with lots of fixes for serious and more niche
issues. Read for more info my &lt;a href="httpxyz.html"&gt;announcement post for httpxyz&lt;/a&gt;. I
will talk about why we did the fork and how we approach it. The event is fully
booked and there is a wait list.&lt;/p&gt;
&lt;p&gt;As the organizer of Python Leiden, I am happy to be checking out another Python
meetup group.&lt;/p&gt;
&lt;p&gt;Plus, I&amp;rsquo;m excited to be giving a talk on HTTPXYZ; my first blog post about it
got a lot of views on Hacker News but not (yet) so much adoption in real life,
and we definitely need to &amp;ldquo;spread the word&amp;rdquo; more.&lt;/p&gt;
&lt;p&gt;I look forward to giving my talk &amp;amp; see you there!&lt;/p&gt;
&lt;p&gt;&lt;img alt="PyAmsterdam flag" class="small" src="images/pyamsterdam-flag.png"&gt;&lt;/p&gt;
&lt;p&gt;Check the details for the
&lt;a href="https://www.meetup.com/pyamsterdam/events/313647263/"&gt;Meetup.com event&lt;/a&gt;&lt;/p&gt;</content></entry><entry><title>Why I forked httpx</title><link href="https://tildeweb.nl/~michiel/httpxyz.html" rel="alternate"/><published>2026-03-25T22:00:00+01:00</published><updated>2026-03-25T22:00:00+01:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-03-25:/~michiel/httpxyz.html</id><summary type="html">I forked the python library httpx to httpxyz after over a year without a release of this popular package</summary><content type="html">&lt;p&gt;Yesterday I forked &lt;a href="https://github.com/encode/httpx"&gt;httpx&lt;/a&gt;. The new fork is
called &lt;a href="https://httpxyz.org"&gt;httpxyz&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Reasons for the fork&lt;/h2&gt;
&lt;p&gt;HTTPX is a very popular HTTP client for Python. There is lots of code depending
on it.&lt;/p&gt;
&lt;p&gt;In 2024, I contributed zstd content decoding. This got merged and released! I
was very happy and proud. Then I found out it was broken. I contributed a fix.
The fix was ignored and there was never any release since November 2024. Me,
and others, asked repeatedly for a release containing my fix. I sent email to
the author personally. I got response when I added that I was considering
forking. The author replied &amp;ldquo;1.0 development is on course&amp;rdquo;. Which is probably
true but it has been in the planning for over two years now
&lt;a href="https://github.com/encode/httpx/pull/3069"&gt;ref&lt;/a&gt;. Even the &amp;lsquo;patch level&amp;rsquo;
release for 0.28.2
&lt;a href="https://github.com/encode/httpx/pull/3525"&gt;has been in draft for over a year&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And apart from this, there&amp;rsquo;s:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recently issues have been made hidden on the github repository, and
  discussions have been turned off. Having issues hidden makes it more
  difficult for people to contribute to the package but also to use the package
  since issues are linked all over in code and documentation also. See
  &lt;a href="https://www.reddit.com/r/Python/comments/1rl5kuq/anyone_know_whats_up_with_httpx/"&gt;reddit thread&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;There has been talk about an upcoming 1.0 release for years now, back to 2020
  or so. In a discussion from October 2024, it was laid out that the 1.0 might
  look very different than the current version of httpx. Simon Willison added
  his points eloquently, please
  &lt;a href="https://github.com/encode/httpx/discussions/3344#discussioncomment-14170874"&gt;read them&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Probably as a result, both
  &lt;a href="https://github.com/openai/openai-python/blob/acd0c54d8a68efeedde0e5b4e6c310eef1ce7867/pyproject.toml#L12"&gt;openai&lt;/a&gt;
  and
  &lt;a href="https://github.com/anthropics/anthropic-sdk-python/blob/d7c0974ce6ab94ca135b10b2a45308203c0e0c7e/pyproject.toml#L12"&gt;anthropic&lt;/a&gt;
  python packages, that depend on httpx, have put guards in their
  pyproject.toml to not install version 1.0.&lt;/li&gt;
&lt;li&gt;The author previously added breaking changes in minor updates, causing churn
  for many people, stating &amp;ldquo;&lt;em&gt;The &lt;code&gt;httpx&lt;/code&gt; package is not yet at a 1.0 SEMVER
  release&lt;/em&gt;&amp;rdquo; &lt;a href="https://github.com/encode/httpx/discussions/3436"&gt;ref&lt;/a&gt;. It&amp;rsquo;s
  pre-1.0, that is right, but if so many people use your package a bit more
  consideration for compatibility seems in place.&lt;/li&gt;
&lt;li&gt;The author also created Django REST framework, and turned off issues and
  discussions there, a little over a year ago. This made life for people using
  the product more difficult
  &lt;a href="https://github.com/orgs/encode/discussions/11#discussioncomment-12311196"&gt;ref&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The author also created MkDocs, of which an interesting
  &lt;a href="https://fpgmaas.com/blog/collapse-of-mkdocs/"&gt;blog post&lt;/a&gt; was published
  recently. Some patterns seem to be recurring.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All this together made me think creating a fork is the best way forward, to
provide a stable path for people invested in httpx.&lt;/p&gt;
&lt;p&gt;I do understand about maintainer burnout, and preferring to work on &amp;lsquo;next&amp;rsquo;, and
that there is life outside of Python, but I think not doing anything for
maintenance and also not letting other people help out in maintaining, for such
a high profile module, is problematic.&lt;/p&gt;
&lt;p&gt;I do hope that Kim will go on to make much more beautiful software and that
there will be a HTTPX2 that will be excellent!&lt;/p&gt;
&lt;h2&gt;FAQ&lt;/h2&gt;
&lt;h3&gt;Q: Why did you fork?&lt;/h3&gt;
&lt;p&gt;See all the reasons above&lt;/p&gt;
&lt;h3&gt;Q: So what is the plan now?&lt;/h3&gt;
&lt;p&gt;Maintain a stable fork of httpx. No great rewrites, no breaking changes, no big
changes to the project setup (for now). The motto is: &lt;em&gt;Move a little faster and
not break things&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Q: But are you not also going to burn out? Surely it&amp;rsquo;s lots of work&lt;/h3&gt;
&lt;p&gt;There has been &lt;em&gt;no&lt;/em&gt; release since 2024 for httpx. A little more frequent would
go a long way. My buddy &lt;a href="https://sanderwegter.nl"&gt;Sander Wegter&lt;/a&gt; is a
co-maintainer to spread the load.&lt;/p&gt;
&lt;h3&gt;Q: Why is your code on Codeberg and not on Github?&lt;/h3&gt;
&lt;p&gt;I feel that as a tech community we have put too many eggs in one basket. GitHub
has been great for developers over the years, but I&amp;rsquo;m worried about the
monoculture. Codeberg is still a little &amp;ldquo;rough&amp;rdquo; but for most intents and
purposes, it just works. You can see the repository
&lt;a href="https://codeberg.org/httpxyz/httpxyz"&gt;here&lt;/a&gt;. Codeberg is run as a non-profit
instead of by a megacorp. Plus, I spoke with a bunch of them on FOSDEM this
year and they&amp;rsquo;re very nice people.&lt;/p&gt;
&lt;h3&gt;Q: Should I port all my code &lt;em&gt;now&lt;/em&gt;?&lt;/h3&gt;
&lt;p&gt;If you want, you&amp;rsquo;d be welcome. But if everything just works for you now, I&amp;rsquo;m
not sure it&amp;rsquo;s warranted. The idea is that there &lt;em&gt;is&lt;/em&gt; a path for you if you need
it. That said, we&amp;rsquo;re
&lt;a href="https://codeberg.org/httpxyz/httpxyz/src/branch/main/CHANGELOG.md"&gt;fixing lots of bugs&lt;/a&gt;.
&lt;em&gt;UPDATE: with our new fixes we changed this position; httpxyz is much faster
now than httpx and has much less bugs, we encourage everyone to upgrade!
&lt;a href="httpxyz-one-month-in.html"&gt;ref: httpxyz one month in&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Q: but what about plugins?&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;d use &lt;code&gt;import httpxyz as httpx&lt;/code&gt;, many things will just work. And for
packages that itself depend on httpx, if you &lt;code&gt;import httpxyz&lt;/code&gt; before you load
that package, you&amp;rsquo;ll use our new package instead. See
&lt;a href="https://httpxyz.org/httpx-compatibility/"&gt;httpx compatibility&lt;/a&gt; I think that
with the 0.3.0 release we&amp;rsquo;ve covered all bases, if you still have problems,
please just open &lt;a href="https://codeberg.org/httpxyz/httpxyz/issues"&gt;an issue&lt;/a&gt; and
I&amp;rsquo;m sure we can figure it out!&lt;/p&gt;
&lt;p&gt;Thanks, and have fun!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Discussion on Hacker News
&lt;a href="https://news.ycombinator.com/item?id=47514603"&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content></entry><entry><title>Talk at Leiden Software Meetup on finger</title><link href="https://tildeweb.nl/~michiel/finger.html" rel="alternate"/><published>2026-03-11T22:00:00+01:00</published><updated>2026-03-11T22:00:00+01:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-03-11:/~michiel/finger.html</id><summary type="html">I'm giving a lightning talk on the finger protocol!</summary><content type="html">&lt;p&gt;On Thursday 19th of March 2026 I will give a lightning talk on the humbe
&amp;ldquo;finger&amp;rdquo; protocol, its history and my re-implementation in Python &amp;amp; SystemD at
&lt;a href="https://leiden.dev/"&gt;Leiden.dev&lt;/a&gt;, the Leiden Software meetup. This is a
monthly meeting in Café de Keyzer which is held at every third Thursday of the
month. In a cozy setting you can talk with other software people and enjoy
talks on different subjects.&lt;/p&gt;
&lt;p&gt;I look forward to giving my talk &amp;amp; see you there!&lt;/p&gt;
&lt;p&gt;Register for the
&lt;a href="https://www.meetup.com/leidendevs/events/313572345/"&gt;Meetup.com event&lt;/a&gt;&lt;/p&gt;</content></entry><entry><title>65 lines of Markdown - a Claude Code sensation</title><link href="https://tildeweb.nl/~michiel/65-lines-of-markdown-a-claude-code-sensation.html" rel="alternate"/><published>2026-02-12T08:00:00+01:00</published><updated>2026-02-12T08:00:00+01:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-02-12:/~michiel/65-lines-of-markdown-a-claude-code-sensation.html</id><summary type="html">AI hype trains</summary><content type="html">&lt;p&gt;Yesterday my employer organized an AI workshop. My company works a lot with AI
supported code editing; using Cursor and VS Code, GitHub Copilot. Plus we do
custom stuff using AWS Bedrock, agents using Strands and so on, all the stuff
everyone is working with nowadays.&lt;/p&gt;
&lt;p&gt;Our facilitator explained how custom rules files can be so very helpful for AI
tooling. He linked to this extension with
&lt;a href="https://github.com/forrestchang/andrej-karpathy-skills"&gt;Karpathy-Inspired Claude Code Guidelines&lt;/a&gt;
as an example. Apparently this plugin is very popular! Yesterday morning the
project had 3.5K stars and at the end of the day this already increased to
3.9K. That&amp;rsquo;s a lot of stars.&lt;/p&gt;
&lt;p&gt;I went on to investigate what this extension actually does and found that it&amp;rsquo;s
just
&lt;a href="https://github.com/forrestchang/andrej-karpathy-skills/blob/main/CLAUDE.md"&gt;one Markdown file of 65 lines long&lt;/a&gt;
that lays out four principles; the first one is &lt;em&gt;&amp;ldquo;Think Before Coding&amp;rdquo;&lt;/em&gt;, added
with some packaging to make it install in Claude Code.&lt;/p&gt;
&lt;h2&gt;Publishing it as a Cursor extension&lt;/h2&gt;
&lt;p&gt;But I don&amp;rsquo;t use Claude Code, so I fired up Codex CLI and turned it into an
&lt;a href="https://marketplace.visualstudio.com/items?itemName=MichielWBeijen.andrej-karpathy-skills-cursor-vscode"&gt;extension for VS Code&lt;/a&gt;
and for
&lt;a href="https://open-vsx.org/extension/MichielWBeijen/andrej-karpathy-skills-cursor-vscode"&gt;Cursor&lt;/a&gt;,
which is a fork of VS Code but uses a plugin registry from the Eclipse
Foundation.&lt;/p&gt;
&lt;p&gt;&lt;img alt="vscode extension" src="images/karpathy-extension-vscode.png"&gt;&lt;/p&gt;
&lt;p&gt;Getting the plugins published was the most work. On the &amp;lsquo;VS Code Marketplace&amp;rsquo; I
am not a &lt;em&gt;Verified Publisher&lt;/em&gt; meaning I do not get a green check mark next to
my name, and you will get a warning if you want to install my extension. And
apparently the only way to get rid of that is to wait for six months with at
least one extension published and then apply for verification. So starting
August I can apply for that and any new extensions get automatically trusted.&lt;/p&gt;
&lt;p&gt;For Cursor the process felt very cumbersome: I had to create an account on
&lt;a href="https://open-vsx.org"&gt;open-vsx.org&lt;/a&gt;, create an Eclipse Foundation account,
link those accounts, link to my GitHub account, sign an Eclipse agreement, and
finally create a GitHub Issue to &amp;lsquo;claim&amp;rsquo; my VS Code Marketplace namespace.&lt;/p&gt;
&lt;h2&gt;Using the extension&lt;/h2&gt;
&lt;p&gt;So, what does using the extension actually feel like? Because of the
non-deterministic nature of these models, I found it hard to tell. I tried a
simple refactoring, and I had the idea that it was very reluctant in making
changes. Was the result better? I&amp;rsquo;m not really sure.&lt;/p&gt;
&lt;p&gt;Typically, your Cursor rules would list the constraints for &lt;em&gt;your&lt;/em&gt; environment,
explaining what coding standards to adhere to, architectural constraints and so
on. I get that, it makes sense.&lt;/p&gt;
&lt;p&gt;I find it wild to think that a company spends millions and millions of dollars
on training a model, with tons of engineers meticulously improving output, and
then some guy comes along and writes 60 lines of text including &lt;strong&gt;Think before
coding&lt;/strong&gt; in the rules and &lt;em&gt;that&lt;/em&gt; would make all the difference.&lt;/p&gt;
&lt;p&gt;But the original repository has almost 4,000 stars, and surely, 4,000
developers can&amp;rsquo;t be wrong?&lt;/p&gt;
&lt;p&gt;Please try for yourself! Install the extension, don&amp;rsquo;t forget to
&lt;a href="https://github.com/mbeijen/andrej-karpathy-skills-cursor-vscode"&gt;star my repository&lt;/a&gt;
and see the results.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Paul Simon" src="images/paul-simon.jpg"&gt;&lt;/p&gt;
&lt;p&gt;As Paul Simon wrote: &lt;em&gt;These are the days of miracle and wonder&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://news.ycombinator.com/item?id=46986001"&gt;Discussion on Hacker News&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content></entry><entry><title>My issues with ProtonMail</title><link href="https://tildeweb.nl/~michiel/protonmail-issues.html" rel="alternate"/><published>2026-02-05T21:21:00+01:00</published><updated>2026-02-05T21:21:00+01:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-02-05:/~michiel/protonmail-issues.html</id><summary type="html">Some issues I have with the mail service I would like to love</summary><content type="html">&lt;p&gt;I use my own domain for email, which I&amp;rsquo;d recommend to everyone. I was on a
cheap Hetzner &amp;lsquo;web hosting with email&amp;rsquo; plan before, which wasn&amp;rsquo;t ideal. During
last November&amp;rsquo;s Black Friday sales I got a ProtonMail subscription and moved my
domain there. But I&amp;rsquo;ve run into several issues, some with how their product
works, others specific to my setup.&lt;/p&gt;
&lt;h3&gt;Can not open some mails on mobile&lt;/h3&gt;
&lt;p&gt;A small percentage of emails simply won&amp;rsquo;t open on iOS. When I tap them, the app
briefly shows the subject, then closes. I can&amp;rsquo;t read the content. These same
emails work fine in the web interface.&lt;/p&gt;
&lt;p&gt;This is a serious problem: your mail client should be able to read mail! I
haven&amp;rsquo;t been burned yet, but I worry about the day I need to show a boarding
pass or concert ticket at the door and can&amp;rsquo;t open it.&lt;/p&gt;
&lt;p&gt;I realized there is a workaround for this: opening the web interface in my
mobile browser, but that&amp;rsquo;s far from ideal. ProtonMail has confirmed the issue
and says they&amp;rsquo;re working on a fix.&lt;/p&gt;
&lt;p&gt;&lt;img alt="ProtonMail iOS failing to open an email" class="small" src="images/protonmail-ios-cannot-open-mail.avif"&gt;&lt;/p&gt;
&lt;h3&gt;Mail spoof warning does not show in mobile app&lt;/h3&gt;
&lt;p&gt;My employer recently switched payroll providers. ProtonMail warns that their
mail server isn&amp;rsquo;t properly configured and the messages could be spoofed, yet
coworkers on Gmail or Outlook see no such warning. After checking with our
security officer, we concluded the mails are valid and ProtonMail is being
overly cautious.&lt;/p&gt;
&lt;p&gt;&lt;img alt="ProtonMail desktop showing spoof warning" class="small" src="images/protonmail-desktop-mail-spoof-warning.png"&gt;&lt;/p&gt;
&lt;p&gt;The strange part: this warning only appears in the web interface, not the iOS
app, or on the Android app.&lt;/p&gt;
&lt;p&gt;&lt;img alt="ProtonMail iOS showing no spoof warning" class="small" src="images/protonmail-ios-no-spoof.png"&gt;&lt;/p&gt;
&lt;p&gt;If there were an actual spoofing attempt, I&amp;rsquo;d want to know, especially on
mobile! I&amp;rsquo;ve raised this issue with Proton support.&lt;/p&gt;
&lt;h3&gt;Mail read flags do not seem to sync between mobile and desktop&lt;/h3&gt;
&lt;p&gt;Emails I&amp;rsquo;ve read on my phone sometimes show up as unread in webmail later.
&lt;a href="https://www.reddit.com/r/ProtonMail/comments/1q82b2r/protonmail_unread_flags_not_synchronizing_between/"&gt;Others on Reddit&lt;/a&gt;
report the same thing, and Proton has confirmed they&amp;rsquo;re investigating. This is
table-stakes stuff for a mail client.&lt;/p&gt;
&lt;h3&gt;Pulsating menu in ProtonMail&lt;/h3&gt;
&lt;p&gt;When I open the context menu in a message, it &amp;lsquo;pulsates&amp;rsquo;. A minor issue, but
it&amp;rsquo;s been there for over two months, testament to the lack of polish in their
apps. This only happens on iOS; a co-worker on Android doesn&amp;rsquo;t see it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="ProtonMail iOS pulsating context menu" class="small" src="images/protonmail-ios-pulsating-menu.avif"&gt;&lt;/p&gt;
&lt;h3&gt;No third party mobile clients&lt;/h3&gt;
&lt;p&gt;ProtonMail encrypts all data at rest and decrypts on your device. Nice in
theory, but it means no standard IMAP, so you can&amp;rsquo;t use your favorite mail
client directly.&lt;/p&gt;
&lt;p&gt;The workaround is installing the ProtonMail Bridge on your laptop, which
decrypts locally and exposes IMAP for Thunderbird, Outlook, etc. But this
doesn&amp;rsquo;t work on mobile. There you&amp;rsquo;re stuck with their app or the web interface.&lt;/p&gt;
&lt;p&gt;I use Linux with ProtonMail in a browser tab; I don&amp;rsquo;t love the Bridge approach.&lt;/p&gt;
&lt;h3&gt;No instant search in webmail without local indexing&lt;/h3&gt;
&lt;p&gt;Another consequence of client-side decryption: search doesn&amp;rsquo;t just work. For
full-text search, your browser has to download and index all your mail locally.
This takes a long time initially.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I really want to love ProtonMail. They&amp;rsquo;re steward-owned, privacy-focused,
European, and building out a full suite of products (VPN, calendar, etc.). But
their core product is email, and it has too many rough edges. I expected better
from a company that&amp;rsquo;s been around this long and is this popular. I&amp;rsquo;ll be
migrating elsewhere soon.&lt;/p&gt;
&lt;p&gt;That said, most of my issues are with the iOS app. Android users likely have a
better experience.&lt;/p&gt;</content></entry><entry><title>Reinout van Rees on prefect.io</title><link href="https://tildeweb.nl/~michiel/reinout-python-leiden-20260122.html" rel="alternate"/><published>2026-01-22T21:00:00+01:00</published><updated>2026-01-22T21:00:00+01:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-01-22:/~michiel/reinout-python-leiden-20260122.html</id><summary type="html">Summary of Python Leiden talk</summary><content type="html">&lt;p&gt;Reinout is a long-time visitor of the Python Leiden meetup. In fact, he is a
regular on most nearby Python meetups and conferences. The nice thing is that
he also writes summaries of the talks he attends and he publishes those on his
&lt;a href="https://reinout.vanrees.org/weblog/"&gt;blog&lt;/a&gt;. I really appreciate this! Today he
gave a talk at our meetup, and I decided to &amp;lsquo;return the favour&amp;rsquo; so here is my
summary of his talk!&lt;/p&gt;
&lt;p&gt;Reinout discusses &lt;a href="https://prefect.io"&gt;prefect.io&lt;/a&gt;: it is a server that
provides a dashboard, has an API, shows workflows, and allows you to
start/restart jobs, examine logs, and such.&lt;/p&gt;
&lt;p&gt;In his company much IT-related work involves loading data from web APIs,
transforming it in some form, loading it in databases and so on.&lt;/p&gt;
&lt;p&gt;Previously this was all done on the command line and people had to log in over
SSH and there were constraints about rotating ssh keys which all made it very
cumbersome. Now they have a nice web UI and not so much IT restraints and it&amp;rsquo;s
much easier for people because they can just log in to a web UI and click
around.&lt;/p&gt;
&lt;p&gt;In Prefect, workflows are defined. Workflows consists of one or more tasks.
Those tasks are written in python. Prefect comes with some niceties to
configure retries on your tasks, it provides a custom logging framework and a
lot more. In the UI you can manually start jobs, configure workers, and monitor
progress.&lt;/p&gt;
&lt;p&gt;Prefect does not provide its own authentication mechanism at the moment. So if
you want to &amp;lsquo;protect&amp;rsquo; it people are using HTTP Basic auth.&lt;/p&gt;
&lt;p&gt;It comes with a docker setup, which is what Reinout is using. Also a hosted
version is available.&lt;/p&gt;
&lt;p&gt;Reinout created a cookiecutter template that allows non-programmers to create
simple python tasks. This has built in workflow that creates a github
repository, and configures github actions that creates docker containers on
every commit on main, and pushes those to a docker registry.&lt;/p&gt;
&lt;p&gt;He uses &amp;lsquo;watchtower&amp;rsquo; in the docker compose setup, which allows him to simply
deploy the stack once, and the stack will poll for updated containers and keep
itself up to date.&lt;/p&gt;
&lt;p&gt;I think it&amp;rsquo;s nice to see that they are able to provide a frictionless way to
set up, deploy and monitor data jobs for people who are more data-minded and
not hardcore sofware developers!&lt;/p&gt;</content></entry><entry><title>JPEG XL Test Page</title><link href="https://tildeweb.nl/~michiel/jxl.html" rel="alternate"/><published>2026-01-21T17:30:00+01:00</published><updated>2026-01-21T17:30:00+01:00</updated><author><name>Michiel W. Beijen</name></author><id>tag:tildeweb.nl,2026-01-21:/~michiel/jxl.html</id><summary type="html">Test page that includes a JPEG XL image</summary><content type="html">&lt;p&gt;This page shows a JPEG XL image, if your browser can handle it! At this point
in time (January 2026) this more or less means only Safari will display the
image, as far as I know. See also &lt;a href="https://caniuse.com/jpegxl"&gt;Can I Use&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="images/jpegxlman.jxl"&gt;&lt;/p&gt;
&lt;p&gt;The person in the image is &lt;a href="https://sneyers.info/"&gt;Jon Sneyers&lt;/a&gt;, co-author of
the JPEG XL spec and also creator of the &amp;ldquo;Free Lossless Image Format&amp;rdquo; that came
before it.&lt;/p&gt;
&lt;p&gt;I find JPEG XL interesting because of its history. It once was implemented in
Chrome, but hidden behind a feature flag. Then Chrome said that it did not saw
enough usage, which is unsurprising, really, and it was removed. Now they
blessed it again and are re-adding it! Some of this story is found on the
&lt;a href="https://en.wikipedia.org/wiki/JPEG_XL"&gt;JPEG XL Wikipedia page&lt;/a&gt;&lt;/p&gt;</content></entry></feed>