This week I discovered Starsailor for the first time. Based on their age and Spotify numbers, they’re not exactly a hidden gem. But it seems like they never quite broke through to the mainstream either. I had just never heard of them before.
Specifically, their debut album Love Is Here. I’ve listened to it so much this week. It’s such a great record, filled with great songs. Their music is raw, punchy, expressive, emotional. There’s so much going on in the arrangements, and structure, and lyrics.
I don’t want to go deep into an analysis, or into how some of their songs remind me of Mando Diao’s Give Me Fire, another fantastic album. This post is just a recommendation. Give them a listen. Maybe you, or someone else reading these lines, will be discovering them for the first time as well, and their music will touch you just as much.
This video from Waffle House swept into my Recommendations today. It starts kind of unhinged, then quickly gets fully unhinged and just keeps its trajectory towards insanity.
At Waffle House, cooks remember their orders by putting packets and other seemingly random stuff on a plate, and the types and positions of the packets tells you what order it is. Like, putting an upside down jelly packet with a mustard packet on the bottom of a plate means: scrambled eggs with 3 eggs and wheat bread. The packets are the “markers”. Want some hash browns? Cook sprinkles some hash browns at the top of the plate. Want those hash browns steamed? A butter cup is added.
The customer doesn’t get the markers, they’re removed from the plate before it goes to the customer.
Insanity.
It reminded me of my weird keyboard shortcut “system”, just without the upside-down mustard packets.
A must-watch, in my opinion.
Timo
When contractors tell you they’ll come on a Saturday at 8:30 am (!!!), then they actually show up at 11:30 am and do nothing except say they want to come again next Saturday at 9 am
Timo
I’ve added a small /ai manifesto to explain how I use generative AI on this site (and also outside of it).
I’m currently working on adding an OAuth/OIDC authorization server at work. Claude told me twice, on different occasions, to just implement the OAuth provider from scratch. No library, just raw-dog OAuth and OIDC completely from scratch. It said it would be worth it, because it’s only ~500 LOC.
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.
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.
Timo
I dreamed about a Technology Connections video where Alec explained that the Advent wreath was invented to improve TV remote signal strength in winter. You would aim through the candles, and it helped to turn off the TV during cold winter nights.
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.
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.
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.
I’ve just released Storage Buckets on Railway. Right now, you can’t make these buckets public. I anticipated that our users might wonder about this, and perhaps feel a bit annoyed that they are strictly private. I wanted to explain the reasoning behind this choice, because I think peeking behind the curtain can be interesting.
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.
In October I wrote a post about a little experiment I implemented. An experiement I wanted to build since I was a teen. Now I’m removing this experiment again.
To recap in short, back in the days when I started to create websites, I was fascinated by the idea that the design of a website (or at least a header image) depicts its own little world, with its own simulated weather and urban scenes and people living there. So I did it, with AI, which renewed the header images every 6 hours.
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!
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).
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.
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?
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.
I’ve been a zsh user for a long time, though I’ve had a bit of a love-hate relationship with it. It’s cool once you get it configured, but there’s so much to configure, and from time to time things would just break or the shell would get annoyingly slow.
On 22 January, 3 days ago at the time of writing, Tailwind v4.0 was released with some major changes. I decided to upgrade today, and the upgrade path was mixed to be honest!
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.
Yesterday I learned two weird things that happen when you use pushState() to navigate to a page with a URL fragment:
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:
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!
The 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 docs, and not in the docs.
Note that never causes a 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 docs. Might be a good opportunity to open a small pull request.
There’s a poster next to my desk with “Only deploy on Fridays” written on it. The poster is visible on Gigs’ Careers page, and from time to time, colleagues and applicants mention it or ask me about it.
I have many thoughts about this topic but I’ll try to keep it short: I don’t like this thought leadership in engineering, where it’s mostly about being aninfluencer and less about having a good influence.
It rubs me the wrong way. You could just say that it annoys me and I should ignore those parts of the internet. But it actually worries me because it feels like small cult-like groups in which engineers won’t grow: They’re caught in an echo chamber, which makes them feel like they’re growing, but instead of growing as a person and engineer, only a single opinion grows within them.
When adding dark and light mode to your site, a common approach is to store the theme in localStorage and reading it on the next visit. But our JavaScript usually runs after the page loads, so reading it in JavaScript can cause a flash of the wrong theme—like flashbanging dark mode users with light mode. We can fix this with a small script in the <head>. But wait—isn’t that a blocking script? Aren’t those bad? Let’s take a quick look at why that’s not always true.
Scenario: a magical fairy—the “magical” is important, so you don’t confuse it with a boring non-magical fairy—appears and grants me one wish. What would I wish for?
That JavaScript switches to snake_case over night. We wake up and all the camelCase is gone, replaced by beautiful snake_case.
This isn’t a matter of personal taste. camelCase is simply more difficult to read. It requires more visual effort. There’s even a study on that.
We’re used to reading words that are visually separated, and the underscore provides that visual separation. You probably had no issues reading this sentence, even though it was mostly lowercase letters. But writingLikeThis madeItLikely aBitMoreDifficult toRead, didn’t it?
JavaScript is not a visually appealing language. Perhaps Java and Smalltalk were not the best influences. And with all the new question marks added to its syntax, it looks like a very insecure “mocking spongebob” meme.
And I won’t buy the argument that camelCase is more efficient because you don’t have to type the underscore all the time! It’s as if developers spend their whole day just typing, non-stop, without autocomplete, constantly having to find those keys to press! Aaaaah help, where’s my underscore key gone now, I can’t find it!!!
Nah. snake_case would have been the better choice.
For the past three years, there hasn’t been a single night when I couldn’t fall asleep or even struggled to do so. The secret? Simply enjoy the moment.
Who would have thought that opening the windows several times a day would have a lasting effect on reducing the humidity in my home? My parents, probably. And probably everyone else except me.
Don’t get me wrong, I did air the rooms in my apartment regularly! But most of the time, not multiple times a day. For example, I aired my bedroom most days. Maybe I forgot to do it once a week, but I usually do it after I roll out of bed. But in the fall season, the humidity has always been at the upper limit before it’s too high.
I guess I was a bit ignorant because after opening the window for about 15 minutes, the humidity quickly returned to where it was before. I thought this would happen every time, no matter how many times I opened the window. But somehow I forgot the most logical conclusion: that doing it multiple times a day will incrementally dry out the room more and more.
After only 2 weeks of airing all the rooms several times a day, it’s now at a perfectly average level. And my windows are not fogging up as much overnight. I even bought a dehumidifier last year, which helped a bit, but in retrospect wasn’t necessary. I should’ve just opened the damn windows more than once a day.
To be honest, it’s a bit embarrassing to admit my ignorance. But I have learned something!
I think some apps I use every day, like Spotify for Desktop or YouTube TV, are being way too careless with seemingly small UI changes. It starts to annoy me a lot, so I put together some examples of sloppy and irresponsible UI changes that I noticed in Spotify and YouTube TV to make you think twice before making such careless changes in your apps.
I don’t know if it’s just me, but trash bags lately suck. Something very strange must be happening in the trash bag industry. So strange that I find myself constantly thinking about trash bags to the point where buying them gives me anxiety.
I’ve motivated myself to write shorter posts more frequently! The previous list of headlines (which is now the Archive) added too much friction for writing down some content—not just because I had to come up with a title, but also because a short post on its own page felt a bit … lonely.
After 2 years of writing posts in GitHub Discussions, I’ve now switched to Keystatic. The writing experience is much better: it’s still in my browser, and the media handling is much better! Images and videos became a bit more cumbersome with GitHub Discussions. It wasn’t impossible, just a bit annoying. And that extra friction became an excuse to not writing down some thoughts I had.
I might have been just a wee bit too excited to release this new version. There are some minor tweaks here and there to improve, but pfft, that’s continuous deployment for you!
Early this morning I woke up briefly, it was 6:30am—yes, that’s early morning for me—and heard very faint shower noises. I usually don’t hear anything from my neighbors, but probably because it was so quiet otherwise, I realized that one of my neighbors had to get up now.
And then I remembered that I used to have to get up at about that time when I went to school. To be exact, I always got up at precisely 6:55am. My morning was always timed to the minute to get the most sleep out of it. The whole family had to coordinate who was in the bathroom at what time. I actually went to bed for another 15 minutes after taking a shower, just to make the most out of every minute of sleep.
I recently discovered that Tailwind’s group utility is super useful in web frameworks with nested layouts. I only thought of the group utility for smaller UI components, but you actually can use group to style any element based on any other element in the DOM.
In-ear earbuds are weird, aren’t they? You’ve got those small rubbery mushrooms that you shove into your ear canal to listen to music and you hope there’s no juicy ear gunk on them when you pull ‘em out.
This chair was the best investment I made last year. My butt never gets tired of this chair.
I still use the tilt mechanism as I configured it a year ago. It’s perfect. I lean back a little, a little more, or not at all. In meetings, I like to lean back a lot, put my hands behind my head and just relax.
It’s a good thing I didn’t get the headrest, because you really don’t need it. When I sit upright, I don’t rest my head. And when I lean back, like I said, I like to put my hands behind my head and lean on them, and it’s really comfortable. It would probably be annoying if there was a headrest.
My back pain never came back! I remember I used to have this constant tension under my right shoulder and looking back it was really not good. But since then it’s just gone. Never had any problems again.
If your job involves sitting at a desk a lot, and sometimes your butt starts to get tired, or you have some tension in your back or shoulders, and you’re not short on money, I would highly recommend buying this chair if you’re not short on money. The price tag may seem high for a chair, but when you consider how expensive a good mattress and pillow is, and how many hours you’ll spend on it, it’s worth every penny. #notsponsored
When I moved into my first apartment over 11 years ago, I learned something that I continue to learn on a regular basis: solve the little problems in your life. Realize that they’re just low-hanging fruit, ready to be picked.
Low-hanging fruit is a term I usually think of only in the context of work. And I still do! Thinking and writing about low-hanging fruit in the context of my personal life feels strange to me, but of course they exist.
I never really liked the faucet in the kitchen of my new apartment. It was a little loose, and when you rotated it, the whole apparatus rotated a few degrees. It was tall, and the water always splashed more than usual when it fell into the sink, splattering water all over the dark granite countertop and stove. You couldn’t pull the faucet down, and it didn’t have a sprayer. It was inconvenient and annoying.
But I didn’t do anything about it because… I don’t know why? Because it’s just a faucet? It didn’t occur to me that this was a low-hanging fruit that I could solve. I just lived with the damn thing for 2 years. Until I realized that a new faucet only costs 50€ and is easy to replace. I could fix this annoyance in my life with the least amount of effort.
Even the little wiggle it had could have been fixed in a few minutes without any tools. Yet I never did.
And I began to avoid using it because it annoyed me so much. Instead of washing my hands in the kitchen, I didn’t wash them at all I actually went from the kitchen to the bathroom sometimes and washed my hands there so I wouldn’t have to wipe the counter because the water would splash everywhere.
I wasted 2 years on something I could have fixed with the click of a button on amazon and 30 minutes of “work”.
That’s just one of many. I’ve started to identify and fix more of them in my life, but it always takes some time to realize “yeah, this has been bothering me for a while, and it’s easy to fix”.
So here’s my call to you: identify those low-hanging fruits and pick them. The big things in life are hard enough, and the little things make a difference.
Last week, I tinkered with developing a Shopify App. Shopify’s developer guides are… eh – a mixed bag. What I wanted to do just wouldn’t work. So, when I can’t find an answer in their guides and it’s also not easily googled, I turn to ChatGPT. I don’t often use ChatGPT for this kind of stuff – I still mostly use Google because it’s faster – but I’ve found that searching for Shopify’s subscription guides often leads to forum posts with no clear answers.
The issue with ChatGPT is that it can be so annoying. It’s like talking to that one coworker who never responds directly to your questions, trying to hide that they secretly have no idea what they’re doing. Just give me an answer, Chatty!
Today I learned that you can capture a screenshot with transparent background using Safari’s Web Inspector. That’s nice because Chrome’s Dev Tools can’t do it. It will always capture it with the background. Sometimes I just want to quickly paste an HTML element into Figma without recreating it. Now I have at least one reason to open Safari from time to time!
A few interesting things to mention:
If you zoom in, the screenshot is also more high res, which is nice.
If you select text, the text is also selected in the screenshot. Before you ask: the mouse is not included.
It only makes a screenshot of whatever is in the bounds of the selected element. If the element has a shadow, the shadow is not in the screenshot. You gotta add some spacing around it if you wanna include the shadow.
It also includes any absolute positioned child elements, even if they’re not in the bounds of the element. Which makes sense, you’re capturing the node, which also includes its children.
While the screenshot does not include the background, it does include elements that overlap the bounds of screenshot, even if they’re from a totally different node.
But it doesn’t include all overlapping elements? It’s a bit difficult to explain, let me demonstrate:
I played around with it, and when I remove the inline-block from my name, it is in the screenshot. Interesting, but not interesting enough to try to understand it because it’s likely the most useless knowledge out there.
This was one of the best concerts I have ever seen. I was so blown away after the first song that I had to yell “holy fuck”. It sounded so incredible. The drums were super tight, everyone was putting all their energy into the music, and it’s unbelievable how good Marcel Veenendaal sounds live.
If you’ve never heard of DI-RECT (they’re quite popular in the Netherlands but not so much here in Germany), I highly recommend you check them out. This radio concert is how I found them, and I don’t understand how it only has 20k views.
Lagerfeuer Deluxe, an unplugged concert with 3 artists: Haller, Cäthe and Enno Bunger. Of course, when Enno is in town, I have to go there. Very nice atmosphere, good music and needless to say Enno’s set was just incredible.
A few times a year, I come across an album that completely captures me. I get so hooked on it, and end up playing it on repeat, all day long. This summer, that album is Moby’s Resound NYC.
To be honest, I hadn’t really thought about Moby much lately, except for that one How I Met Your Mother episode where they meet a bald guy on New Year’s Eve and mistake him for Moby. Other than that, his music didn’t really grab my attention much. I mean, sure, I knew some of his banger songs, but that was about it.
But then, someone recommended this new album to me, and after the first minute, I knew that I’ll love it. Resound NYC doesn’t bring in any new songs, but instead it’s Moby’s older tracks from 1994 to 2010 in new orchestral arrangements. These versions are all absolute bangers. They’re both familiar but also refreshingly new.
Those songs were all influenced by his life in New York City, hence the title: Resound NYC. In a series of short videos on YouTube, Moby shares the stories behind each track. He talks about what life was like in NYC during those times, what he was going through personally, and how each song came to be. How he was living in decimated neighborhoods that were hit hard by the crack epidemic of the 80s and 90s, and even how we was living in an abandoned factory…? It’s super interesting, inspiring and emotional.
There’s also the album Reprise from 2021, which also consists of new versions of his older songs, but Resound NYC is just… a whole new level. Interestingly enough, both albums feature the track “Extreme Ways”, and listening to both, you immediately notice how Resound NYC is much more vibrant and cinematic.
Even though Resound NYC made me listen to the original versions again, I just like the Resound NYC versions much more. And maybe that’s by design. Why would he want to make something worse? He transformed it from the music he wanted to release 25 years ago, to the music he wanted to release in 2023.
Went there with Chris, was a great night. I am a huge fan of Maarten. His solo music is much more chill than Balthazar, and it’s definitely different and slower compared to a Balthazar concert. But the guy is great, an incredibly talented musician. And I love it when he holds his guitar up under his chin.
Marteen’s concerts, both for Balthazar and Warhaus, are not just songs from the album but-it’s-live. Instead, he rethinks the songs and how they could work live, creating a very unique experience.
The first solo was kind of weird? It felt like the guitarist and the drummer had no idea what to do. But maybe they were just being musical geniuses, who knows.
Found myself getting totally lost in the music, just vibing along, no sense for time or space. (Besides the fact that the sound guy seemed to have a problem which he apparently couldn’t fix until the end)
I missed the dark humor of seasons 1-3, where it always felt like a mix of “that’s a whoopsie” and “oh geez” from the very first episode. This is what made Fargo so unique to me. Season 4 felt more like “holy…” – and only after a few episodes.
It was still quite compelling in its own way, had some unexpected twists, and there were some elements of dark humor present. Though the dark humor focused mostly on weird deaths, instead of the typical chain of unfortunate circumstances. At least the unnecessary, yet fun, paranormal stuff wasn’t removed.
One of my goals for this year is to get better at taking breaks from work. But, honestly, I’m doing a terrible job at it. Whether it’s taking a lunch break, calling it a day, or taking a little coffee break: I don’t stop when I should stop. I keep telling myself I’ll do better, but in the moment, I screw up. And it’s not because work is stressful or too much is expected of me – it’s my own fault.
The problem is, I’m always telling myself that I’ll just finish this one small thing that’ll only take 2 minutes. But then 5 minutes pass, and another 5 minutes, and another, until half an hour has gone by. And suddenly, I’ve only got a short lunch break before the next meeting starts. It’s funny how in this situation I keep looking at the time, seeing how it flies, and I’m just like, “Oh God, I should get going…” but I don’t do it. Even though I should just get up and go. I’m such a dingus.
I know that I don’t have to respond to messages right away. No one expects an immediate response. But it’s just one message, which then turns into a few messages, and then a longer conversation. Or when doing code reviews, I tell myself that I’ll just write those few last comments and finish up the whole review (even though nobody would be mad if I submit only half a review, and do the next half later). Or when I’m coding, just a few more lines of code.
It’s always small tasks that, for some reason, I think will be done in 2 minutes.
But I always feel like I have to get it all done, or else it’s going to occupy my mind all through lunch or the next day. But will it really? Like… really?
Two weeks ago, I took a day off and didn’t check Slack even once. I woke up to a bunch of notifications on my phone, and without reading them, I paused all work-related apps. And you know what? I didn’t check them all day. This surprised me because I usually open Slack automatically, like how you open TikTok, but not while you’re sitting on the toilet. That was a win!
The thing is, I keep telling myself I’ll do better tomorrow, but then I relapse the day after. It feels like an endless cycle. It makes me less motivated to do better. Even though I know I should just take a goddamn break.
There’s a Christmas song on YouTube that has a special place in my heart. I’ve been listening to it every holiday season since its release in 2011. Music has a way of taking us back to memories, and whenever I hear this song, I’m transported back in time. I used to take for granted that it would always be available to me on YouTube, but that all changed in Christmas 2021.
All of a sudden, the song was nowhere to be found.
Chris Coyier is well-known for blogging a mind-boggling amout of posts on CSS-Tricks (which is now owned by DigitalOcean). But I’m not going to talk about his stuff on CSS-Tricks, but instead about his personal blog chriscoyier.net.
Chris’ blog feels like a stream of consciousness. It’s just what he’s thinking about at the moment, without any deeper meaning or learning. And yet, those thoughts are still interesting and fun to read. Annoyed at System Fonts in macOS? Just blog about it. Orange favicons work great for light and dark themes? Why not write down that thought, then notice that Safari is weird, and end it with “Time for a nap”. It’s refreshing to see someone share their half-baked ideas without feeling the need to make a grand conclusion or provide a takeaway for the reader. You can just end your post if you don’t know what else to write.
It feels like a conversation with a friend. Sometimes you just want to talk about something that’s been on your mind without worrying about whether it’s profound or even fully formed. It’s totally normal in a conversation to suddenly end your thought mid-sentence with a big ol’ shrug. And that’s what his blog feels like to me.
Maybe we sometimes try too hard to offer some kind of education or to present ourselves as experts? At least I sometimes feel that way. But I don’t think that’s necessary. It’s nice to take a break from expert content and just read something that’s relatable and human.
Chris has definitely inspired me to post more half-baked thoughts. And to not think about words and sentences and publishing too much. Just write it down, press the big button, and continue with your day.
I bought a fully loaded Herman Miller Aeron Remastered Chair, and have been sitting on it for the last two weeks. Fun Fact: Aeron stands for “an expensive Ron”. So you’re asking what it’s like to sit on Ron?
I felt like posting random stuff sometimes. Not only babble about software development tips. So I added this new Offtopic section. Although I called it Stream in the Sidebar because Offtopic is a long word?
Anyways, what started with a new category ended in a switch from Markdown to MDX and a dark mode, mainly because I’m often looking at my blog at night and it hurt me poor eyes. I’m not completely done, there are a few things I’d like to add and improve, but shipping is good.
I imagined some cool aurora borealis vibes going on, but didn’t yet spent too much time in Figma to make it a bit more like I imagined. I need to change some pictures of previous posts to fit into the dark theme. And some old posts were moved into the Offtopic section because it made more sense. In summary: things happened.
There are some really good and well produced concerts on arte Concert. In the past weeks, I’m totally obsessed with this live session from Kid Francescoli. It’s not only chill music, but also visually very appealing. The setting on a boat makes for some really cool camera shots. Due to the lack of an audience, it has kind of a lonely undertone to it.
There’s a version on YouTube which cannot be embedded, hence the screenshot of a still frame. 🙃 Or alternatively on the Arte Mediathek
I only realized a few years ago that arte is actually kind of an interesting channel. When I was a teen and still watched a lot of TV, I thought that arte is just an artsy experimental TV station for snobs. It always felt odd when they were airing something appealing and interesting, because aren’t they supposed to be weird? Maybe arte is still just an artsy channel for snobs, and I’m the one who became a snob?
I also watched this Live Show from the Parcels a few times in the past weeks. It’s not from arte, but I thought I just mention it. I watched a lot of those live sessions while I’m coding in the past weeks. Don’t know where that’s coming from.
Do you remember when I told you the story how I developed this blog using Next.js, getStaticProps and Incremental Static Regeneration? Well, we’ve got some new features in Next.js, which we’ll explore here. This is the story of migrating to a new very much still experimental feature.
There’s a high chance that your .gitignore file includes a bunch of stuff which doesn’t belong in there. In my opinion, it should only include paths which belong to your software project. For example build artifacts, 3rd party packages, and specifics to the language or runtime of your software.
A few months ago, an email from my good friend Gerrit showed up in my inbox. Gerrit made a new “Pottoriginale” movie, and he needed a website for his film tour. I knew that it will only take me an evening to do, I had the feeling that I’d enjoy the challenge, and I knew that I have some time in the coming week. And a few days later, pottoriginale.de was live.
I’ve always found Productivity Apps ✨ cool ✨. Nice-looking Apps for Todos and Notes, as a single source of truth for everything going on in my life. But I learned that I don’t work like that. Those Apps always felt wrong. I’m very organized without them. For some reason, I’m still envious of people when they show how they use some App to organize their life, but I don’t try them out anymore.
I mainly use Emails, my Desktop, Calendar, and Post-It’s. I know it sounds ridiculously oldschool, but it works pretty well for me. Let me explain:
Last week I got a new sofa, and it’s one of the most stressful changes I had in the past.
Big changes are not an issue for me. 10 years ago, when I moved into my very first apartment and lived alone for the first time: no worries at all. It was exciting!
But I struggled so hard with buying a new sofa. It took me a year to get myself to buy a new one. It’s big and comfortable, looks nice, it’s exactly what I wanted. But all the consequences of that change:
I had to move all the furniture in my office, so my old sofa fits in there. Getting rid of my old sofa wasn’t an option. But now I’m sitting in a different direction on my desk. It just feels wrong. The room looks nice and cozy, but it’s so different. My mic boom arm now doesn’t fold away easily because it bangs against the wall. Do I also need to move that thing? So many changes!
I always folded my laundry on top of the backrest of my old sofa. It was nice. I could watch TV while folding up my tees. But I cannot do that anymore with my new sofa.
In programming, we often deal with things being in a state. Users being verified, Modals being open, Posts being published. Yesterday I had an interesting chat with Daniel about rules to decide when you should store state as an enum1or as a boolean. We both know that it’s always better to use enums instead of booleans. It’s a common advice and nothing new, just search it on the internet and you’ll see countless articles recommending the use of enums.
But how can we tell that a boolean should rather be an enum?
Blog your heart! Blog about something you’ve learned, blog about something you’re interested in. Blog about cameras or HTML or that one browser bug you’ve noticed this morning […]
Ignore the analytics and the retweets though. There will be lonely, barren years of no one looking at your work. There will be blog posts that you adore that no one reads and there’ll be blog posts you spit out in ten minutes that take the internet by storm.
That’s exactly the philosophy I want to follow here. And that’s also the reason why I focused on building a blog which allows me to publish content as frictionless as possible.1
Chris’ blog inspired me to finally start blogging again. His blog is a mixture of smaller and larger development topics, mixed with other thoughts and stories from his life. Sometimes I messaged him with some small development thoughts or things I learned that day, and he often responded with “that would be a nice little blog post”.
And he’s right! You just need to overcome the thoughts “that’s not worthy of publishing” and “nobody cares”. At least I had to overcome them.
When I published my new site last week, I continued to still see my old site. Initially I thought it was just DNS, but after a short while it dawned on me, that my old site used a Service Worker which cached everything and made it offline available. When you visited my old site, it automatically installed the Service Worker, and continued to serve it from cache. And now, if you visited my new site, it still served my old site. Great.
git rebase --onto is one of my absolute favorite git features. I don’t use it every day, but when I use it, it’s super helpful. For all those situations where you branched off a branch before it got merged, and then you need to rebase your branch onto main without handling dozens of conflicts.
In my last post I covered my decision to use GitHub Discussions as CMS for my posts. I’m going to build it using Next.js, because that’s what I already use a lot, and it has some features which will become quite useful. Let’s get cracking!
When I was a teen, I learned how to build WordPress themes. During holidays or when school was out, I vividly remember how I sometimes sat in front of my computer for a few days and nights, and created new themes for my blog. Of course I had no blog, but having one was a cool thought. But this stuck to me, and I was really never happy with how my blogs work. Until now!
I tried cutting pizza with scissors today because I heard only good things about it and
holy fuck I hated it, there wasn’t a single good thing about it.
Regular Friday morning:
make coffee
reboot the light switches
Pro-Tip: using BigInt() in your code makes it look 10x more important.
I was juggling storage sizes today. 9 petabytes in bytes already hit MAX_SAFE_INTEGER. 9PB is a lot but also isn’t.
What my dentist thinks I’m doing in the hour before my appointment vs. what I’m really doing
No better sunday than breakfast and an Outdoor Boys video.
Some popular hosting platforms taught developers the wrong assumption that every hosting-adjacent feature must be built into the platform or bought as another SaaS, when in reality, you often just need to run a docker image.
Gotta reeducate.
Had my first unproductive day in 3 months. Thanks to MacBook issues.
One day. In 3 months. Just because of tech problems. Not because of meetings or calls or metawork.
Actually I’m not even mad, that’s amazing.
me: blocks ntp in firewall on homelab vps tunnel
vps: time drifts out of sync, google oauth breaks
me: surprised_pikachu.png
work this week be like
MEX 🛬 FRA 🚄 CGN
I thought I can escape jetlag, but I just slept for 12 hours.
I just waited 2 hours for my bag at FRA airport until I was told it’s in a separate baggage claim near the train station, because I have a connecting train.
Who tf designs this crap. A train is not a plane, don’t treat it like one. Against user expectation.
Notably, it’s mostly about dependencies. Dependencies are entropy. When everything can be a dependency of everything else, entropy reaches its maximum. Activity ceases.
Heat death of a codebase.
There are three base ingredients for a scalable codebase: Modules, Layers and Interfaces.
Modules to tame data dependencies. Layers to tame function dependencies. Interfaces to tame dependency boundaries.
Ham’s blog now also features “Moments”, as a way to share smaller thoughts and everyday moments on his own site.
Love to see more people adopt this way of sharing their thoughts outside social media platforms, just on their own websites. I really, really like following the people I care about. I just don’t want to open Twitter or Bluesky most of the time.
Slowcial media, baby!
TIL the United States has no transit zone, so you need to go through US immigration for a connecting flight.
The german in me thinks this is very inefficient.
I fell asleep while a Vsauce YouTube Short was playing on my tablet.
I woke up over 6 hours later. It looped fucking 400 times.
the arrow between buckets and services has landed
Bought some melatonin today to combat jetlag next week.
I had to try one out. idk why but it always fascinates me that medicine actually works. i’m so fucking sleepy
Just imagine how much time and money has been wasted on reimplementing shitty versions of iOS’s wheel picker.
I just released Buckets on Railway. This is huge for me.
I came to Railway because I want to give developers truly great experiences. And this is exactly the stuff.
A rush of adrenaline, relief, and positive feedback. No idea how I should be able to sleep now. It’s 2:15am.
Replica Metrics (one of my first projects at Railway) is now in GA! You can check how your replicas are doing, spot hot or underutilized regions, and catch replicas going wild.
TIL there’s a german PhD thesis from 1978 about guys injuring their junk by sticking it into a hoover. It lists 16 medical cases.
Case 14 is about a guy cleaning up and curiosity got him.
Case 15 is about case 14’s father who wanted to prove his son lied.
He did not lie.
It’s mindblowing what’s possible within a week.
I started adding Buckets to Railway on Monday. Today, 5 days later, I can create a Bucket in a project, click deploy, copy the credentials from the frontend, and upload files to it.
That’s kinda crazy.
Infra as Code doesn’t gift you confidence.
You’re only as confident in your changes as you are in the tool.
If it feels like magic and you don’t understand it, it makes you less confident, not more.
devs when they implement permissions
There comes a point where a 3rd party API is just so ill-designed that you can’t think of any way to abstract it nicely, and you just add a big comment block to explain what the actual fuck is going on.
i’m cooking rn 👀
more like yeetest amirite
You call it a memory leak. I call it unlimited caching, baby.
In other news: I’ve set up cross-posting to Bluesky and Twitter. I’ll be happy if you read my shit here, but you can also read on Bluesky and Twitter. I really like the idea of having my own place, where people can come and read what I’m up to, outside of a big social media platform.
This post should be crossposted to my blog, to Twitter and to Bluesky. Poggies if this works. (edit: it did!)
I started adding storage Buckets into Railway this week. It’s Day 2, and I can already create and deploy a Bucket.¹
I’m excited af about this because I’ve always experienced Buckets as this boring table UI in some cloud console, and to create a Bucket you had to fill out a huge form. But look at this! Right-click, Bucket, boom, here you go, now build stuff with it!
¹ right now the Bucket is just an empty shell and you can’t yet do anything with it. But tomorrow is the day where I will turn it into something usable
Share every small win. When you’re on a roll and have one small win after another, just share them. A big win is just a collection of many small wins over time. It helps you notice the progress you’re making, and as a nice side effect, others will notice too.
I can now post images! I can just send sent them to my Discord bot and ✨ they are here. Discord even supports alt text which is really handy.
To verify this works, here are two DALL-E images I recently generated.
Most of the code I’ve written today could’ve been written by Claude, with some manual intervention and guidance in between. Because it was a lot of work where you look at similar implementations in the codebase and do roughly the same, which AIs are generally good at.
But
Then I would’ve only learned a tiny fraction about the existing code, and I likely wouldn’t understand half of it. By doing everything by myself, I learned so many things about the codebase that will be massively helpful in the future.
Test Test
Hello?
Is this thing on?
I also built a small Discord bot with n8n to automate posting. I added it to my private Discord server (which I use for various stuff), and whenever I post into a specific channel, it creates a new post here!
Tomorrow: crossposting to other socials. I think. Or maybe images first.
I added short posts as a new post type. Basically as an alternative to posting on Bluesky or Twitter. Like in the old days.
It’s scrappy, there’s a bug in timezones with relative times, and I want to add a bunch of stuff. But I can use it.
I still don’t feel like I want to open Bluesky or Twitter. It pulls me in too much and messes with my inner peace. But I’ll definitely set up some cross-posting in the future, and I also want to pull in likes (and maybe comments? dunno yet) from socials.