til uvx deno

deno is a modern Javascript runtime that can run Javascript and Typescript natively. But it is also something that's available to all Python users without the need to install node. Thanks to uv, just run uvx deno and you're all set!

I've used it in a project where I want to have some simple unit tests for Javascript via happy-dom but it's also usable as a task runner via uvx deno task build. It effectively let's you skip the node toolchain for a bunch of simple use-cases, it's great!

til flock

2026-04-21

When you auto-deploy with a bash script from cron, the naive setup is something like this:

* * * * * /path/to/deploy.sh

This deploy.sh script checks if the current git hash is up to date with the main repo. If not, we want to trigger a new build locally and redeploy.

But this has an issue. Cron fires every minute, but docker build might a fair bit longer. Before you know it the second run starts while the first is still building, and now you've got two two builds getting into each-other.

It turns out there's a fix: wrap it in flock.

* * * * * flock -n /tmp/marimo-deploy.lock /path/to/deploy.sh

What flock does:

  • It grabs an exclusive lock on the file /tmp/marimo-deploy.lock.
  • It runs the command while holding it.
  • Next, it releases the lock when the command exits.

The -n (non-blocking) flag is the key bit: if the lock is already held, flock exits immediately instead of queueing up. So if a build is still running when the next cron tick fires, the second invocation doesn't run.

One issue with the setup is that the deploy script could hang for whatever reason. So it's best to always add a timeout for this as well.

* * * * * flock -n /tmp/marimo-deploy.lock timeout 10m /path/to/deploy.sh

Feels like a nice pattern for those homelab moments where you don't want a webhook to push into your machine and you want to pull from GitHub on occasion instead.

tailwind shows why mcp might survive

I've been a huge fan of tailwind for over half a decade. Partially because it's a great library but also because it was cool to see a small team ship and maintain a functional business while maintaining it. It's been tough to see they had to lay off most of their engineers because of LLMs and I was happy to see them get back in the ring with a new product: ui.sh.

The experience of ui.sh is pretty interesting too. From the outset, it just looks like a skill that tells the LLM to be more helpful in design tasks. One of my favorite features is that it can make 4 designs for your site that you can review as part of the feedback cycle. It's a nice touch.

But if they had made a new business out of sharing a few text files they'd be ripe for total disruption again. So instead, the skill points to an MCP that they have full control over. The agent can talk to it, but only if I keep paying for the service.

And that is almost more interesting. The MCP hype never really landed with me, but this setup makes a lot of sense. The MCP lets businesses connect to agents in a way that a CLI never really could. You could find ways to inspect the CLI, but you can't see what's on the other side of the MCP wall.

And if this is a way for great projects to maintain their standing, I'm all for it.

minimalism as a harness

LLMs have a much easier time if it is clear that there is one, and only one, way to do something.

Python, ironically, isn't that. It's too flexible. But a language like Lua is! It only has one container object and it is also delightfully lightweight to run.

And on top of that, it turns out that there's a delightfully minimal, but batteries included, 2d game engine called LÖVE that really gets you a prototype quickly.

So I gave it a spin and it turns out you don't even need to worry about game assets! LÖVE comes with APIs for graphics, fonts, sounds and even music. It's got everything you need to generate all of it!

So basically, with an engine like that, you're getting mighty close to zero-shotting a first prototype. It does help if you have a simple game in mind and if you can point to a variation of an existing game. So I went for the bacteria puzzle from 7th guest. I barely had to explain this game and it could just immediately go for it.

The only thing that I missed while exploring this was a notebook environment for this space. Something similar to what Bret Victor talks about here.

More than anything, that feels mighty tempting to explore some more!

Until then, the minigame can be played here.

you win while training

2026-04-10

Back when I was rowing in college a teammate said an incredibly memorable thing:

You don't win a rowing match during the match, you win it during the training.

Few things ring as true as this and the attitude deserves to be repeated.

You're free to keep an outcome in mind, but outcomes require preparation. And that preparation is where it is at.

legos vs 3d printers

Let's say, as a dad, that there are two cool kinds of creative toys you could make with your kid.

  1. You buy a 3d printer, and print what-ever creative thing you two can come up with.
  2. You buy lego, and take things apart together when you want to make an adjustment.

The 3d printer is way more flexible in what shapes it can create. But once it's created, you cannot change it anymore. The only thing you can do is to put down the shape, walk to the computer and then re-design. Then, you have to wait for the 3d printer to print the new shape and hope for the best because there is a disconnect between holding something in your hand and seeing a design plan on a screen.

Lego is different. Don't like a part? Take it out, and swap it. Not only is this fun, but you are actively using your hands the whole time! By interacting with the shape, you also become better at creating it. It's a super direct feedback mechanism, very different to the 3d printer.

The reason I bring up this story is because it describes why I still like to code, be it manually or agentically, in Python notebooks. It allows me to think more about the pieces of legos that I want to have and how they are going to click together. This lets me play and understand the problem I am trying to solve much better. And it also gives me the ability to quickly iterate on my ideas. Even when I decide to drop a lego-piece for now, I can still easily pick it up again later. It's also a lot easier to explain what the code is doing to a 3rd party when you have the right widgets/elements.

I've met peers who prefer to fully vibe code an app for each and every use-case. There's a place and a time for that. But that feels too much like a 3d-printer to me and sometimes I want software that's just more like legos.

video game write-offs

2026-04-08

It seems that companies might have very good reasons to hang on to a video game IP even if they have no intention of using it. I imagined this would mainly be to prevent another company from using the IP, but Michael Cain, a developer on Arcanum, has another reason: taxes!

When Microsoft bought Activision, they had to assign a dollar value to every "dead" IP they acquired—including Arcanum. Let’s say they assigned it a value of $5 million.

If Microsoft decides they will never make Arcanum 2, they can write that $5 million off as a total loss to lower their tax bill.

So that means that if anyone wants to buy the IP, even if Microsoft is never planning on doing something with it, it can still be more valuable to sit on it. It's worth more as a tax-shield than a source of revenue.

the light of a CPU

Just quoting this tweet.

I would like to make my apologies for defending M$, but I must from time to time. I have to put respect on github for handling the amount of shit code that has been added over the last 3 months. literally 10s of billions of lines of code that will never see the light of a CPU

It does a good job of describing something that I've been wondering. How many of those lines of code are written only to never ever run anywhere?

once the ball is rolling

2026-04-07

It can be hard to go from 0 to 1. But once you're there, it's much easier to go from 1 to 2.

I was reminded of this today when I looked at the YT stats for the marimo channel. It took 6 months to get our first 500,000 views. But it only took 3 months to go from 1,000,000 to 1,500,000.