Skip to main
a head full of oat milk cappuccinos by
Timo Mämecke
Jump to navigation

15 posts earlier this year

Shorts

View all
Timo’s avatar

I wish dependabot were a tiny bit smarter. Like: biome’s config has the version in its schema URL. So if dependabot updates biome, the schema version doesn’t match the installed version anymore, and it will complain. Just do it for me, pls.

Timo’s avatar

If your crons on Railway were running a bit late recently, they should be better now. I rolled out a few updates between 18:30 and 19:30, and there are clearly some significant changes in cron timing.

A few late stragglers here and there, but we’ll catch those too.

Graph of Crons fired. After 6:30pm clearly visible spikes every 5 minutes in cron executions.
· 1 minute read

Reading less short message social media

I stopped scrolling through Bluesky for a month, and I really enjoyed that month.

Even though Bluesky and Mastodon are much nicer places than Twitter, I realized that I don’t enjoy the experience of scrolling through short message social media. There are a few posts here and there that are nice or funny or interesting, but if there’s just a one post that I don’t want to read or think about, the whole experience is ruined for me.

It’s not about keeping your feed clean of extremism and other bullshit. It was easy to keep my feeds clean on Bluesky and Mastodon. But people think and post about a lot of different things, and I’m just not interested in all of them, nor do I want to spend any amount of mental capacity thinking about them. Scrolling past them is difficult. I have to force myself not to read something I’m not interested in. And that just makes it not a great experience.

I subscribe to a YouTube channel because I’m interested in the kind of content they make, and I assume that future content will be similar. And I follow people on Instagram because I like the pictures they post. But short message services just give me too much variety in what to expect.

So, I will continue what I did for a month. I deleted the Bluesky app from my phone and removed it from my browser bookmarks. I’ll still cross-post my posts there, because of course I want to reach an audience. And maybe I’ll post the occasional meme there. (Why not post them here?) But for now, I don’t want to consume text feeds.

· 1 minute read

URL Fragments and pushState() are weeeiiird

Yesterday I learned two weird things that happen when you use pushState() to navigate to a page with a URL fragment:

  1. The CSS :target selector doesn’t work. You can use :target to style an element that is the current URL fragment when doing a full document load, but not with pushState! This is also documented on MDN:

    The target element is set at document load and history.back(), history.forward(), and history.go() method calls. But it is not changed when history.pushState() and history.replaceState() methods are called.

    But that’s weird! Why not? I would argue that it makes :target a little bit unusable in modern web applications. Even though it’s such a useful feature!

  2. The hashchange event doesn’t fire. Even though the hash changes, the event doesn’t fire. This is also documented on MDN, but oddly enough it’s documented in the pushState docs, and not in the hashchange docs.

    Note that pushState() never causes a hashchange event to be fired, even if the new URL differs from the old URL only in its hash.

    That’s weird! And unexpected. This note should be included in the hashchange docs. Might be a good opportunity to open a small pull request.


Update: I did indeed open a small pull request and the hashchange docs now also explain this behavior.

· 3 minute read

If you’re using Next.js’ Middleware for authorization, you’re doing something wrong

Whenever the topic of authorization in our Next.js apps came up at Gigs, I had a very strict opinion and rule: we don’t use the middleware for authorization. We can use the middleware for some optimistic UI patterns, like an early redirect when a user is logged out, but never as a means to grant a user access to some data. I’m not saying this because I hate the middleware, or because it’s an easily predictable vulnerability, but because of the way the Next.js middleware sits in an application.

Read more
· 1 minute read

GitHub Releases as RSS Feed

Quick tip: You can follow GitHub Releases in your feed reader. Just add .atom to the end of the releases URL. For example:

https://github.com/glanceapp/glance/releases
👇
https://github.com/glanceapp/glance/releases.atom

You can do the same with other GitHub resources—like commits, users, tags—if that’s useful to you. But I find the releases feed super handy. Sometimes I just wanna stay in the loop on certain software, like apps, frameworks, major libraries, services, databases.

· 8 minute read

How and when should I actually migrate my database?

For a long time, across different projects throughout my career, I’ve seen database migrations happen during application startup. These migrations usually run as part of a post-deployment hook, just before the new deployment receives any production traffic. But… what’s happening in this short (or sometimes longer) timeframe after the migration is done and before the new app boots, while the old app is still active?

Read more
· 2 minute read

I’m using em dashes—but I’m not an AI

Please don’t make the em dash—the long hyphen I’m using here—an indicator of AI-written text. I recently saw a post on LinkedIn (it pains me to admit it) where someone wrote a script to hide all comments containing an em dash because they’re highly likely to be AI-generated. I think there’s truth to it. But I also hate the fact that I think there’s truth to it.

Read more
· 12 minute read

A Better Button Component with Composition

Do I really need to write an introduction to button components? We all know them. Buttons are one of the most commonly used components in our user interfaces, and are also some of the messiest components, with crappy interfaces and complex implementations for something as simple as a freaking button, and they only get worse as your codebase ages.

In this post, I’ll briefly explain why button components are a classic problem in software engineering, how composition can solve this problem, and how I implement complex buttons with simple code these days.

Read more
· 4 minute read

Vary for images on Cloudflare CDN for free

Let’s rebuild a paid Cloudflare feature … on Cloudflare, for free.

Vary for images is a Cloudflare CDN feature that caches multiple variants of the same URL, based on the browser’s specific capabilities. It’s a paid feature. I want it, but I didn’t want to pay for it. That’s no issue, because we can rebuild this functionality on Cloudflare completely for free, with just a bit more configuration.

Read more
· 1 minute read

I don’t like many of my development-related blog posts for one reason: I often feel like I spend too much time explaining the problem instead of getting straight to the point.

Understanding the problem is just as important as understanding how to solve it. So I don’t want to skip explaining the problem properly. And I want to include readers who might not be familiar with the topic. But whenever I start writing, I imagine readers rolling their eyes in light of the “obviousness” of it all.

I often think back to “Words To Avoid in Educational Writing” by Chris Coyier. He warns against using certain common words that make readers feel dumb. Just because you find something obvious doesn’t mean they do.

I’m certainly guilty of using those words myself sometimes, but the message stuck with me. That’s why I always try to explain problems thoroughly: because the reader might not know this yet, and it could be valuable knowledge for them, and I want them to feel included.

Still, I can’t shake the insecurity. Whenever I explain a problem, I worry readers will think that I’m a bit of a dum-dum for explaining something “everyone” already knows. Even when editing my posts before publishing them, I spend most of my time refining the problem explanation, trying to make it not too long but still explain everything.

Do I explain problems too much? You can tell me, I can take it!

· 1 minute read

More than 15 years ago, I had this idea to autogenerate the header image of my website based on the current time of day, season, location, and a simulated weather pattern that naturally progresses. It fascinated me to have a long-running, realistic-feeling, autonomous system that changes itself without my involvement—like its own little world. I liked the idea to open my own site and being surprised by what I see. “Oh, it’s snowing!”, then seeing the snow melt away some time later, or observe the bleakness of misty autumn days.

Back then, I tinkered with layering PNGs on top of each other to create “random” scenes, but it looked terrible. I can design websites, but I can’t draw nice pictures.

I never ended up doing it because 1) I didn’t miraculously become a good artist, and 2) who cares.

Well, I care. I’m older now, and the fascination is definitely weaker, but I still thought about it every year. When my most favorite time of year starts, I get this itch. And this year, I finally scratched it.

AI made this much easier to solve. Not just for creating the images, but also for simulating the weather progression based on the time of day, the season, and previous days. Everything is now truly unpredictable, there isn’t a single line of code where I can already guess what will happen next.

New scenes get generated four times a day, and I feed the AI with previous days to create a natural progression.

I’m storing all the prompts, images and weather simulations (in a Railway Bucket of course).

1 post last month

· 2 minute read

Question: “Why no public buckets on Railway?”

This question came up a few times, and it’s not an easy yes or no. They will come at some point, with more time. In the end, this was kinda my onboarding project and I have to scope stuff.

Public Buckets are good for static sites, but it’s already easy to host static sites on Railway. Buckets are cheaper, but the added benefit for the platform isn’t as huge as private buckets, so they weren’t high on the list of priorities.

Bucket UX is not super easy to get right, and many providers solve this with a list of configurations and assuming that users will know what they all mean and when to use them. Public buckets have lots of footguns. It’s not rare to hear about security incidents involving wrong configuration of public buckets. For most things that aren’t just static assets, you want a backend for authorization.

For caching and saving egress on static assets, CDNs work great. I’m using Cloudflare’s CDN for my stuff, and we’re also cooking on making it easier to add a CDN.

Is the solution just a “public” checkbox? Maybe it will be, but it’s not super clear to me if it really is the best way. If I would’ve went down that path and added it, it would’ve likely resulted in more than just a checkbox. It risks turning into a configuration hell where you don’t really know what those settings will actually do, and combined with the security issues, the end result risks causing more issues. Maybe even so many more issues that I’d rather want to remove it again to solve it better in the future, but you can’t simply take features away.

Ideally we have something that doesn’t require you to know what a bucket actually is, what the difference between a bucket and a CDN is, and what “public” or “private” actually means. Something that works perfectly for what you’re trying to build.

1 post last week

· 4 minute read

Intentionally left ugly

My favorite process in software engineering, whether I’m building something new or working on an existing feature, is to first focus purely on the functionality and completely ignore the design. Once everything works, I shift my full attention to making it look and feel great.

I learned this process over a decade ago, and I’ve been recommending it ever since to anyone who’s struggling while building something: struggling with refactors, with design collaboration, with pressure from planning and management, or simply with finding creative direction for the UI.

Read more