<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Bakker Labs</title><description>Web development agency specializing in fast, SEO-optimized websites with a focus on simplicity and quality. We also offer expert copywriting to enhance content and rankings.</description><link>https://bakkerlabs.com/</link><item><title>Conceptual integrity and counting lines of code</title><link>https://simonwillison.net/2026/Aug/19/conceptual-integrity-and-counting-lines-of-code/</link><guid isPermaLink="false">https://bakkerlabs.com/links/conceptual-integrity-and-counting-lines-of-code/</guid><description>Simon Willison on why lines of code might actually mean something with coding agents, and how agent-generated software grows like the Winchester Mystery House.</description><pubDate>Thu, 20 Aug 2026 00:00:00 GMT</pubDate></item><item><title>The Duskbloods: FromSoftware goes multiplayer</title><link>https://www.theguardian.com/games/2026/aug/20/the-duskbloods-fromsoftware-feature</link><guid isPermaLink="false">https://bakkerlabs.com/links/the-duskbloods-fromsoftware-multiplayer-battleground/</guid><description>FromSoftware&apos;s Elden Ring pedigree applied to an 8-player free-for-all on Switch 2. Marrying players with bouquets, turning into a dinosaur, final battles that spike your adrenaline. Sign me up.</description><pubDate>Thu, 20 Aug 2026 00:00:00 GMT</pubDate></item><item><title>Data centers: this feels too relevant to me</title><link>https://www.newyorker.com/cartoon/a62045</link><guid isPermaLink="false">https://bakkerlabs.com/links/data-centers-this-feels-too-relevant-to-me/</guid><description>Two men standing in front of a data center. One says: this one is set aside for storing accidental screenshots of your phone&apos;s home screen.</description><pubDate>Mon, 10 Aug 2026 00:00:00 GMT</pubDate></item><item><title>Homeownership, one thermostat at a time</title><link>https://bakkerlabs.com/notes/homeownership-one-thermostat-at-a-time/</link><guid isPermaLink="true">https://bakkerlabs.com/notes/homeownership-one-thermostat-at-a-time/</guid><description>Installed an ecobee smart thermostat this week. Now I know what a C-wire is, that my furnace has a control board, and that HVAC is a whole system with parts tha</description><pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Installed an ecobee smart thermostat this week. Now I know what a C-wire is, that my furnace has a control board, and that HVAC is a whole system with parts that break in expensive ways. I didn’t plan on learning any of it, but there’s something satisfying about fixing your own house and understanding a little more each time.&lt;/p&gt;</content:encoded></item><item><title>Building pi in a World of Slop — Mario Zechner</title><link>https://www.youtube.com/watch?v=RjfbvDXpFls</link><guid isPermaLink="false">https://bakkerlabs.com/links/building-pi-in-a-world-of-slop-mario-zechner/</guid><description>Time to install Pi coding agent and practice discipline.</description><pubDate>Fri, 07 Aug 2026 00:00:00 GMT</pubDate></item><item><title>Reddit is out, RSS is back</title><link>https://bakkerlabs.com/blog/reddit-is-out-rss-is-back/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/reddit-is-out-rss-is-back/</guid><description>Deleting Reddit and going back to RSS. Self-hosting FreshRSS, reading on NetNewsWire. No algorithm, no infinite scroll.</description><pubDate>Thu, 06 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I deleted Reddit off my phone last week. Not just logged out. Deleted.&lt;/p&gt;
&lt;p&gt;The thing that finally did it was the recommendations. Every time I opened the app, the algorithm had decided I needed more doom. More bad news, more outrage, more threads full of people arguing about things that don’t affect me. I’d come away 20 minutes later feeling worse and having learned nothing I wanted to know.&lt;/p&gt;
&lt;p&gt;So I’m going back to RSS. There’s something nice about opening a reader and seeing only the stuff I actually subscribed to. No trending tab, no algorithmic amplification of whatever’s making people angriest today. If a feed gets annoying, I unsubscribe. That’s the whole moderation model.&lt;/p&gt;
&lt;p&gt;I’m self-hosting FreshRSS on my server and reading through NetNewsWire on my phone. A few dozen feeds, 10 minutes in the morning, and I’m done. It ends.&lt;/p&gt;
&lt;p&gt;I should have done this a year ago.&lt;/p&gt;</content:encoded></item><item><title>Why Svelte Is Better Than React in the Agentic Era</title><link>https://zackwebster.com/blog/why-svelte-is-better-than-react-in-the-ai-era</link><guid isPermaLink="false">https://bakkerlabs.com/links/why-svelte-is-better-than-react-in-the-agentic-era/</guid><description>Interesting…</description><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate></item><item><title>Hermes, the orchestrator, and the art of walking away</title><link>https://bakkerlabs.com/blog/hermes-orchestrator-and-the-art-of-walking-away/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/hermes-orchestrator-and-the-art-of-walking-away/</guid><description>How I build features by talking to an AI on Telegram and letting autonomous agents do the implementation. A two-model, two-phase pipeline.</description><pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve been building this AI development pipeline for a while and I think it’s finally worth writing down how it works. The short version: I plan with an AI on Telegram, then walk away while autonomous agents implement the feature on a VPS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The split is the whole point.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Phase one is all conversation. I talk to Hermes (my agent framework) through Telegram — just messaging back and forth, refining the spec until it feels right. No markdown files to edit, no PRs to open, no ceremony. Just me and an AI iterating. When I’m happy, I type one command.&lt;/p&gt;
&lt;p&gt;That command kicks off the orchestrator. It’s a custom Python CLI I built called &lt;code&gt;opencode-orchestrator&lt;/code&gt;. It takes the spec, passes it to a cheap drafting model for plan generation, then sends that plan to a different (heavier) model for review. Same content, two perspectives, different providers — I’ve found this catches way more blind spots than any single model can.&lt;/p&gt;
&lt;p&gt;Once the plan is reviewed, the orchestrator shards it into tickets and starts executing. Each ticket gets an OpenCode worker in its own git worktree — isolated, parallel where dependencies allow. The worker implements the ticket, runs the tests, and reports back. Then the review model checks the result. Pass or fail, the orchestrator advances the queue automatically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The model split is the part I’m most proud of.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For drafting (plan generation, ticket implementation) I use OpenCode Go. It’s $10/month and fast enough that I don’t think twice about running it. For review I use a completely different model from a different provider. The orchestrator enforces they can’t be the same, which stopped me from cheating and using one model for everything. It’s made a real difference — the review model regularly catches things the drafting model misses, especially around edge cases and non-functional requirements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Real example.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I ran this on the orchestrator itself recently. The feature was a &lt;code&gt;--version&lt;/code&gt; flag. The spec said it should print a version number, and the drafting model implemented exactly that — hardcoded the version string. Tests passed. But the review model flagged it: “This should read from &lt;code&gt;pyproject.toml&lt;/code&gt;, not be hardcoded.” I hadn’t even thought to specify that. The orchestrator kicked the ticket back for a fix, and the second pass got it right. That’s the whole philosophy in miniature — two models, two perspectives, better outcome than either alone.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It’s not all smooth sailing.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The orchestrator hit a real bug on its first contact form run. A VPS reboot left a ticket in an &lt;code&gt;ACTIVE&lt;/code&gt; state, and &lt;code&gt;resume&lt;/code&gt; crashed because the state machine didn’t allow transitioning from active to active. The fix was a one-line change in the state machine, but finding it required digging through logs, worktrees, and process tables. I wrote it up, fixed it, and the next run worked. These are the growing pains of running your own infra — and I kind of enjoy them.&lt;/p&gt;
&lt;p&gt;The Telegram integration makes all of this feel effortless. I don’t need a dashboard or a web UI. I message Hermes, we shape the feature, I drop a &lt;code&gt;resume&lt;/code&gt; command, and the VPS does the rest. I can check &lt;code&gt;orchestrator status&lt;/code&gt; anytime, but mostly I just wait for Hermes to ping me when it’s done. It’s the closest I’ve come to the “describe the feature, get the feature” loop.&lt;/p&gt;
&lt;p&gt;I’m still adding to it. Better worker monitoring, smarter retry logic, maybe a proper dashboard at some point. But for now, this pipeline lets me go from a Telegram message to a working PR without touching a file myself. That’s pretty wild.&lt;/p&gt;</content:encoded></item><item><title>React Query meets React Router</title><link>https://tkdodo.eu/blog/react-query-meets-react-router</link><guid isPermaLink="false">https://bakkerlabs.com/links/react-query-meets-react-router/</guid><description>Great article </description><pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate></item><item><title>1,920 Watts of Freedom</title><link>https://bakkerlabs.com/blog/1920-watts-of-freedom/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/1920-watts-of-freedom/</guid><description>Colorado&apos;s new law lets you plug solar panels into a wall outlet. Up to 1,920 watts. And HOAs can&apos;t stop you.</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I was scrolling Reddit the other day and came across HB 1007, this Colorado law Polis just signed on May 7. It caught my eye because A) I just moved here, and B) I’ve been looking into solar and wading through all the permit nonsense you apparently need.&lt;/p&gt;
&lt;p&gt;Turns out Colorado now has the highest plug-in solar cap in the country, 1,920 watts. You can buy panels, plug them into a standard wall outlet, and start generating power without asking Xcel for permission or getting an electrician involved.&lt;/p&gt;
&lt;p&gt;The part I really like though is that it overrides HOA restrictions and lease clauses. So if you’re renting or in a condo with a balcony, you can still do it. Most solar stuff seems aimed at homeowners with roofs and money. This one actually works for people who don’t own a house.&lt;/p&gt;
&lt;p&gt;1,920 watts of freedom. Not bad for a state that gets 300 days of sun.&lt;/p&gt;</content:encoded></item><item><title>Signed, sealed, delivered, infected</title><link>https://bakkerlabs.com/blog/tanstack-supply-chain-attack/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/tanstack-supply-chain-attack/</guid><description>84 malicious versions across 42 packages, then it spread to Mistral AI, UiPath, OpenSearch. Over 400 versions across npm and PyPI. And they all had valid provenance.</description><pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You might have seen the headlines about TanStack’s npm packages getting compromised. 84 malicious versions across 42 packages, then it spread to Mistral AI, UiPath, OpenSearch, Guardrails AI. Over 400 versions in total across npm &lt;em&gt;and&lt;/em&gt; PyPI within hours. It’s bad. But there are a few things about this attack that make it worse than the usual supply chain drama, and I think they’re worth unpacking.&lt;/p&gt;
&lt;p&gt;First, the technical chain is genuinely clever. The attackers (TeamPCP, same group that hit Bitwarden and SAP earlier this year) exploited three things in sequence: a &lt;code&gt;pull_request_target&lt;/code&gt; misconfiguration in TanStack’s GitHub Actions, cache poisoning across the fork-to-base-repo boundary, and then (this is the wild part) they read the OIDC token straight out of the runner’s process memory via &lt;code&gt;/proc/&amp;#x3C;pid&gt;/mem&lt;/code&gt;. That token was meant for npm’s trusted publishing system. So the malicious packages were published &lt;em&gt;from TanStack’s own CI pipeline&lt;/em&gt;, carrying valid SLSA Build Level 3 provenance attestations. They looked cryptographically authentic. Provenance as a trust signal just broke.&lt;/p&gt;
&lt;p&gt;Second, the worm doesn’t clean up when you uninstall the package. It writes itself into &lt;code&gt;.claude/&lt;/code&gt; hooks and &lt;code&gt;.vscode/tasks.json&lt;/code&gt;, so every time you open VS Code or run Claude Code, it fires again. It also drops a system daemon (&lt;code&gt;com.user.gh-token-monitor&lt;/code&gt; on macOS, &lt;code&gt;gh-token-monitor.service&lt;/code&gt; on Linux) that survives reboots. The threat actor reportedly taunted researchers with a YouTube link and a message saying “We’ve been online over 2 hours now stealing creds.”&lt;/p&gt;
&lt;p&gt;And the exfiltration? It goes over the Session P2P network. Encrypted messenger traffic that looks like Signal, routed through a decentralized swarm. No central domain to take down.&lt;/p&gt;
&lt;p&gt;If you or your team pulled any &lt;code&gt;@tanstack/*&lt;/code&gt;, &lt;code&gt;@uipath/*&lt;/code&gt;, &lt;code&gt;@mistralai/*&lt;/code&gt;, or &lt;code&gt;@opensearch-project/*&lt;/code&gt; packages between May 11-12, rotate everything. Not just npm tokens. GitHub PATs, AWS keys, Vault tokens, Kubernetes service accounts, SSH keys. And check for those &lt;code&gt;.claude/&lt;/code&gt; and &lt;code&gt;.vscode/&lt;/code&gt; files. They don’t go away with &lt;code&gt;npm uninstall&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Anyway. Full writeup with all the IoCs and affected version ranges &lt;a href=&quot;https://safedep.io/mass-npm-supply-chain-attack-tanstack-mistral/&quot;&gt;here&lt;/a&gt; if you want the details. I mostly wanted to flag the persistence and provenance angle because those aren’t getting enough attention.&lt;/p&gt;</content:encoded></item><item><title>New Coordinates</title><link>https://bakkerlabs.com/notes/new-coordinates/</link><guid isPermaLink="true">https://bakkerlabs.com/notes/new-coordinates/</guid><description>Leaving the Netherlands. Driving from New York to Colorado with my wife and the dog.</description><pubDate>Fri, 24 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Leaving the Netherlands. Driving from New York to Colorado with my wife and the dog.&lt;/p&gt;</content:encoded></item><item><title>The demise of software engineering jobs has been greatly exaggerated</title><link>https://edition.cnn.com/2026/04/08/tech/ai-software-developer-jobs</link><guid isPermaLink="false">https://bakkerlabs.com/links/cherry-picking-the-news-the-demise-of-software-engineering-jobs-has-been-greatly-exaggerated/</guid><description>A little bit of good news I needed in my life</description><pubDate>Thu, 09 Apr 2026 00:00:00 GMT</pubDate></item><item><title>Congrats on your first entry</title><link>https://bakkerlabs.com/notes/congrats-on-your-first-entry/</link><guid isPermaLink="true">https://bakkerlabs.com/notes/congrats-on-your-first-entry/</guid><description>Resend&apos;s onboarding is on point. One. Two. Done.</description><pubDate>Thu, 19 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Resend’s onboarding is on point. One. Two. Done.&lt;/p&gt;</content:encoded></item><item><title>Why ‘Silksong’ Took Seven Years to Make</title><link>https://www.bloomberg.com/news/newsletters/2025-08-21/why-silksong-team-cherry-s-sequel-to-hollow-knight-took-so-long-to-make?accessToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb3VyY2UiOiJTdWJzY3JpYmVyR2lmdGVkQXJ0aWNsZSIsImlhdCI6MTc1NTc4NjYzOSwiZXhwIjoxNzU2MzkxNDM5LCJhcnRpY2xlSWQiOiJUMUNMTUpHUFdDUFcwMCIsImJjb25uZWN0SWQiOiJCMUVBQkI5NjQ2QUM0REZFQTJBRkI4MjI1MzgyQTJFQSJ9.oTN8q1m9pNWFv7oW-n3vzq-hRWAxrDx9B7iF80RdTzk&amp;leadSource=uverify%20wall</link><guid isPermaLink="false">https://bakkerlabs.com/links/why-silksong-took-seven-years-to-make/</guid><description>It’s finally happening. I have to admit I never finished Hollow Knight but put more than 60 hours in and loved exploring the mysterious world. Can’t wait for more of that. </description><pubDate>Thu, 21 Aug 2025 00:00:00 GMT</pubDate></item><item><title>Switching from VSCode to Jetbrains IntelliJ </title><link>https://bakkerlabs.com/blog/2025-08-19-switching-from-vscode-to-jetbrains-intellij/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/2025-08-19-switching-from-vscode-to-jetbrains-intellij/</guid><description>I miss you CMD+Shift+P</description><pubDate>Tue, 19 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Honestly the hardest part is the new shortcuts and slight usability differences. Having to double click a file in the explorer for instance has been throwing me off for weeks.&lt;/p&gt;
&lt;p&gt;I can’t seem to find the right way to select every line down/up from my cursor. Or how to select and to add every instance of that selection to the selection. The settings are a mess, I can never find anything even though there seems to be a pretty decent search baked in, it just doesn’t seem to be making sense.&lt;/p&gt;</content:encoded></item><item><title>Metroid Prime Remastered is a masterpiece</title><link>https://bakkerlabs.com/blog/metroid-prime-remastered/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/metroid-prime-remastered/</guid><description>The fact that this is a 23 year old game is insane.</description><pubDate>Tue, 19 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I cannot believe I’m playing a game that came out 23 years ago, yet looks so good. The details are stunning and I never realize the game I’m playing is almost a quarter of a century old.&lt;/p&gt;
&lt;p&gt;I’m only 13 hours in and hopefully not close to the end yet. I’m thinking about it constantly, wishing to be done with work so I can play more. I also just &lt;em&gt;had&lt;/em&gt; to write a little message about it.&lt;/p&gt;
&lt;p&gt;The drops on your visor when it rains in the overworld of Tallon VI, the reflection of Samus when something explodes close to you, the condensation in your helmet- it’s just incredible. And then I haven’t even talked about the atmosphere, the loneliness, beauty, mystery. Or about the music. I really think this game is a masterpiece.&lt;/p&gt;
&lt;p&gt;I don’t know why it took me so long to pick this up, but I’m glad I did. This is a &lt;em&gt;must&lt;/em&gt; play. I can’t wait for Metroid Prime 4: Beyond. If it’s anything like the the first installment, we’re going to be in for a treat.&lt;/p&gt;</content:encoded></item><item><title>Nintendo Switch 2</title><link>https://bakkerlabs.com/blog/nintendo-switch-2/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/nintendo-switch-2/</guid><description>How the Nintendo Switch 2 reignited my love for gaming.</description><pubDate>Mon, 18 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I did something I’ve never done before: I bought a console on launch day. I bought the Nintendo Switch 2 the day it came out. I don’t know why. I mean, I was excited when it was announced and I new I was someday going to get it. But a day before launch I made a very impulsive decision and ordered it straight from Nintendo - yes, they were still available, and the next day it was delivered at my home.&lt;/p&gt;
&lt;p&gt;Initially it was cool, but I also quickly realized it was just the same as the first switch, but better. The magic that made the original Switch special was lacking from the Switch 2. Totally understandable, but it did temper my excitement a little bit.&lt;/p&gt;
&lt;p&gt;But then I started playing. And I kept playing. And I’m finishing games left and right. I think I have picked it up for a substantial amount of time, almost every day since I have it in my home. I have finished Cyberpunk, Echoes of Wisdom and Undertale, I am about halfway through Metroid Prime Remastered and played more than 70 hours of No Mans Sky. I havent even bought/started Donkey Kong Bananza and Mario Kart world and there’s still more to come, Metroid Prime: Beyond and Elden Ring are coming this year and I can’t wait to play those as well.&lt;/p&gt;
&lt;p&gt;I know this is not something I normally write about but this has been all consuming for me. I think this little machine is great, it looks great, it feels great, and it plays great!&lt;/p&gt;</content:encoded></item><item><title>Goals</title><link>https://bakkerlabs.com/blog/goals/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/goals/</guid><description>I’m trying something new. Setting up my three goals to focus on.
</description><pubDate>Sat, 16 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;To keep aligned and focused I’m setting up three goals that I want to focus or improve on. This came to me when trying to hold myself to my first goal of eating no sugar. I needed to have them in my face and I was looking for a solution to make this happen on my phone.&lt;/p&gt;
&lt;p&gt;My current goals are:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No sugar&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I eat a lot of sugar. My friends joke about my love for peanut m&amp;#x26;ms. Every year when Sinterklaas comes around in the Netherlands I eat bags of chocolate Pepernoten. I’m relatively healthy and have no complaints, and I would love to keep it this way. For me and my family.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stop overthinking&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Life is not always as complicated as it seems to us when we’re in it. I’m trying to be mindful of this fact. I don’t want to overthink situations, conversations and relationships. I choose to belief that things can be simple.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exercise&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To finish off the health sandwich I also want to exercise more. I do kickboxing once a week and love it, but know I need to do more to stay in shape. Especially now that I’m entering my mid-lif&lt;/p&gt;</content:encoded></item><item><title>Recreating my favorite text-based internet game from the 90s</title><link>https://bakkerlabs.com/blog/recreating-my-favorite-text-based-internet-game/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/recreating-my-favorite-text-based-internet-game/</guid><description>Full-stack strategy game built with Hono, React, TanStack Router, Drizzle ORM, and Postgres. A decade of learning poured into one project.</description><pubDate>Thu, 24 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the late nineties I used to play an online game that I’ve never really forgotten. Text-based, you played as a province inside a kingdom of up to 25 players, waging war with military, thievery, and magic. Build efficiently, defend, attack. I was obsessed with it.&lt;/p&gt;
&lt;p&gt;It still exists, but it’s been handed between owners and it’s a bit of a mess. So as an exercise in everything I’ve learned over the last 10 years, I built my own version. It’s live at &lt;a href=&quot;https://game.bakkerlabs.com/&quot;&gt;game.bakkerlabs.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What started as a nostalgia project turned into a proper full-stack strategy game. It’s tick-based. Think a simplified version of what Utopia or Earth would look like rebuilt on modern infrastructure. You explore land, construct buildings, train armies, cast spells, form alliances, and attack other players. All the systems you’d expect from a game like this exist behind an API: combat with returning armies, magic with attack/intel/buff spells, an economy driven by population and buildings, and an alliance layer with internal messaging and visibility controls.&lt;/p&gt;
&lt;p&gt;On the backend it’s &lt;strong&gt;Hono&lt;/strong&gt; running on Node.js with &lt;strong&gt;Drizzle ORM&lt;/strong&gt; talking to a &lt;strong&gt;Neon&lt;/strong&gt; Postgres database. I picked Hono because it’s fast and its middleware model is clean. Auth, game state, and admin layers compose cleanly without getting tangled. All business logic lives in pure service functions, which made testing the combat formulas and validation with Vitest straightforward.&lt;/p&gt;
&lt;p&gt;The frontend is a &lt;strong&gt;React SPA&lt;/strong&gt; built with &lt;strong&gt;Vite&lt;/strong&gt; and &lt;strong&gt;TanStack Router&lt;/strong&gt; with file-based routing, no global state manager, all server state through TanStack Query. The router’s type-safe navigation and the way it handles nested layouts (authenticated routes, land-specific views) made a game with lots of different screens feel manageable. Types are shared between backend and frontend so the combat formulas run the same code on both sides.&lt;/p&gt;
&lt;p&gt;The whole thing runs on &lt;strong&gt;my own VPS&lt;/strong&gt; behind a Dockerfile, with &lt;strong&gt;Kinde&lt;/strong&gt; handling OAuth for authentication.&lt;/p&gt;
&lt;p&gt;I’m still adding to it. Stances for strategic specialization, deeper alliance mechanics, and eventually opening it up for real rounds. But it’s playable now. If you remember this genre of browser games, it’ll feel familiar.&lt;/p&gt;</content:encoded></item><item><title>Proper support for Jinja in VSCode</title><link>https://bakkerlabs.com/blog/proper-support-for-jinja-in-vscode/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/proper-support-for-jinja-in-vscode/</guid><description>A quick fix</description><pubDate>Sat, 23 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One thing I’ve been struggling as I’ve been learning Python and Django is proper highlighting of Jinja/HTML files in VSCode. Today I decided to figure it out and I’m here to share it with you:&lt;/p&gt;
&lt;p&gt;Open your &lt;code&gt;settings.json&lt;/code&gt;, either default, for your workspace or your user. You can do this by typing &lt;code&gt;cmd + shift + p&lt;/code&gt; and typing &lt;code&gt;settings json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In this file add the following settings:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&quot;emmet.includeLanguages&quot;: { &quot;jinja-html&quot;: &quot;html&quot;},&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>Hello weird world</title><link>https://bakkerlabs.com/blog/hello-weird-world/</link><guid isPermaLink="true">https://bakkerlabs.com/blog/hello-weird-world/</guid><description>My motto</description><pubDate>Mon, 11 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hello, I’m &lt;strong&gt;Jaap&lt;/strong&gt; and I think a weirder world is a better world.&lt;/p&gt;</content:encoded></item></channel></rss>