<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Russell Bloxwich: Writing</title>
    <link>https://russ.dev/posts</link>
    <atom:link href="https://russ.dev/rss.xml" rel="self" type="application/rss+xml" />
    <description>Essays and project write-ups by Russell Bloxwich on software architecture, AI-assisted development, local-first apps, and homelab.</description>
    <language>en-NZ</language>
    <lastBuildDate>Wed, 15 Jul 2026 00:00:00 GMT</lastBuildDate>
    <item>
      <title>Picking a Language Model Small Enough to Live on Your Phone</title>
      <link>https://russ.dev/posts/on-device-models</link>
      <guid isPermaLink="true">https://russ.dev/posts/on-device-models</guid>
      <description>Benchmarking small language models to run on a phone: why accuracy plateaus at 3-4B, why RAG hurt, and how a deterministic calculator beat the LLM.</description>
      <pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
      <category>On-Device AI</category>
      <category>LLM Evaluation</category>
      <category>AI Agents</category>
      <category>TypeScript</category>
      <category>Software Architecture</category>
    </item>
    <item>
      <title>Gratin: A Recipe App That Never Phones Home</title>
      <link>https://russ.dev/posts/gratin</link>
      <guid isPermaLink="true">https://russ.dev/posts/gratin</guid>
      <description>How I built Gratin, a cross-platform recipe app with no server that can read your data: one React core, Tauri and Capacitor shells, and CRDT sync.</description>
      <pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
      <category>Local-First</category>
      <category>CRDTs</category>
      <category>Privacy</category>
      <category>React</category>
      <category>Software Architecture</category>
    </item>
    <item>
      <title>Replacing Our SQL Parser</title>
      <link>https://russ.dev/posts/parser-poc</link>
      <guid isPermaLink="true">https://russ.dev/posts/parser-poc</guid>
      <description>Rewriting a slow, paid ANTLR SQL parser in two days, 3-20x faster on real customer SQL, using a Ralph Wiggum loop and a corpus of production queries.</description>
      <pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate>
      <category>TypeScript</category>
      <category>AI-Assisted Development</category>
      <category>Software Architecture</category>
      <category>Developer Tools</category>
    </item>
    <item>
      <title>Migrating Off Firestore</title>
      <link>https://russ.dev/posts/parallel-cutover</link>
      <guid isPermaLink="true">https://russ.dev/posts/parallel-cutover</guid>
      <description>A year migrating a frontend off Firestore with dual writes, feature-flagged reads, and SSE for real-time, plus where the abstraction boundary should live.</description>
      <pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate>
      <category>Database Migration</category>
      <category>Software Architecture</category>
      <category>React</category>
      <category>TypeScript</category>
    </item>
    <item>
      <title>Fixing a Slow React App</title>
      <link>https://russ.dev/posts/react-performance</link>
      <guid isPermaLink="true">https://russ.dev/posts/react-performance</guid>
      <description>Fixing a slow React app: why memoization is a bandaid, how Redux selectors and a whole workspace in memory caused it, and what actually worked.</description>
      <pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>Frontend Performance</category>
      <category>State Management</category>
      <category>TypeScript</category>
    </item>
    <item>
      <title>Greenkeeper: A Local Daemon That Babysits Your PRs</title>
      <link>https://russ.dev/posts/greenkeeper</link>
      <guid isPermaLink="true">https://russ.dev/posts/greenkeeper</guid>
      <description>Greenkeeper is a local Go daemon that watches your GitHub PRs and runs your AI CLI in a git worktree when CI fails, conflicts appear, or reviews stall.</description>
      <pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate>
      <category>Go</category>
      <category>Developer Tools</category>
      <category>AI Agents</category>
      <category>AI-Assisted Development</category>
    </item>
    <item>
      <title>Cursor Model ROI</title>
      <link>https://russ.dev/posts/cursor-roi</link>
      <guid isPermaLink="true">https://russ.dev/posts/cursor-roi</guid>
      <description>A sortable React dashboard comparing every Cursor model on price, cache economics, Arena scores, and speed, refreshed from upstream data on a schedule.</description>
      <pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>Developer Tools</category>
      <category>AI-Assisted Development</category>
      <category>Data Visualization</category>
    </item>
    <item>
      <title>Clipboard Inspector</title>
      <link>https://russ.dev/posts/clipboard-inspector</link>
      <guid isPermaLink="true">https://russ.dev/posts/clipboard-inspector</guid>
      <description>A web tool that reveals every MIME type on your clipboard, edits each in Monaco, and copies a faithful ClipboardItem back, with rich previews.</description>
      <pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>Web Platform APIs</category>
      <category>Developer Tools</category>
      <category>TypeScript</category>
    </item>
    <item>
      <title>The Registry Pattern</title>
      <link>https://russ.dev/posts/registry-pattern</link>
      <guid isPermaLink="true">https://russ.dev/posts/registry-pattern</guid>
      <description>The registry pattern: a typed lookup table of handlers behind one interface for notifications and AI tool calls, and why it isn&apos;t the service locator.</description>
      <pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate>
      <category>TypeScript</category>
      <category>Design Patterns</category>
      <category>Software Architecture</category>
      <category>AI Agents</category>
    </item>
    <item>
      <title>Anon: Anonymous All-Hands Q&amp;A With No Server</title>
      <link>https://russ.dev/posts/anon</link>
      <guid isPermaLink="true">https://russ.dev/posts/anon</guid>
      <description>Anonymous all-hands Q&amp;A over WebRTC with no server and no logs, plus an in-browser AI that rewrites your question so your writing style can&apos;t out you.</description>
      <pubDate>Sun, 14 Dec 2025 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>Privacy</category>
      <category>On-Device AI</category>
      <category>Web Platform APIs</category>
    </item>
    <item>
      <title>Frontend Three-Layer Architecture</title>
      <link>https://russ.dev/posts/frontend-architecture</link>
      <guid isPermaLink="true">https://russ.dev/posts/frontend-architecture</guid>
      <description>Applying controller-service-repository thinking to React: view models, state management as a data-access layer, and why feature isolation is a lie.</description>
      <pubDate>Sun, 14 Dec 2025 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>Software Architecture</category>
      <category>Frontend Performance</category>
      <category>State Management</category>
      <category>Design Patterns</category>
    </item>
    <item>
      <title>Interface Driven Development in the Age of AI</title>
      <link>https://russ.dev/posts/interface-driven-development</link>
      <guid isPermaLink="true">https://russ.dev/posts/interface-driven-development</guid>
      <description>Ship AI-generated code without regret by hiding it behind interfaces: contracts, dependency injection, and why the old Java patterns were right all along.</description>
      <pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate>
      <category>TypeScript</category>
      <category>AI-Assisted Development</category>
      <category>Design Patterns</category>
      <category>Dependency Injection</category>
      <category>Software Architecture</category>
    </item>
    <item>
      <title>Local First, Offline First, and Cloud</title>
      <link>https://russ.dev/posts/local-first</link>
      <guid isPermaLink="true">https://russ.dev/posts/local-first</guid>
      <description>Local-first vs offline-first vs cloud: who owns your data, why Evolu and CRDTs make local-first practical, and the Paprika problem waiting to strand you.</description>
      <pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate>
      <category>Local-First</category>
      <category>CRDTs</category>
      <category>Privacy</category>
      <category>Software Architecture</category>
    </item>
    <item>
      <title>Error Handling with Neverthrow</title>
      <link>https://russ.dev/posts/neverthrow</link>
      <guid isPermaLink="true">https://russ.dev/posts/neverthrow</guid>
      <description>Typed error handling in TypeScript with neverthrow: three ways to structure errors across layers, a namespace pattern, and exhaustive switch safety.</description>
      <pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate>
      <category>TypeScript</category>
      <category>Error Handling</category>
      <category>Design Patterns</category>
      <category>Software Architecture</category>
    </item>
    <item>
      <title>Controllers, Services, and Repositories</title>
      <link>https://russ.dev/posts/layered-architecture</link>
      <guid isPermaLink="true">https://russ.dev/posts/layered-architecture</guid>
      <description>Controllers, services, and repositories in TypeScript: hexagonal architecture, why I use classes over functions, and the late-binding trap to avoid.</description>
      <pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate>
      <category>TypeScript</category>
      <category>Software Architecture</category>
      <category>Dependency Injection</category>
      <category>Design Patterns</category>
    </item>
    <item>
      <title>My Monorepo Setup</title>
      <link>https://russ.dev/posts/monorepo</link>
      <guid isPermaLink="true">https://russ.dev/posts/monorepo</guid>
      <description>How I run one monorepo for every side project: shared Pulumi infra, a 15-line SPA deploy, why I avoid Vercel, and why I keep coming back to AWS.</description>
      <pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate>
      <category>Monorepo</category>
      <category>AWS</category>
      <category>Infrastructure as Code</category>
      <category>TypeScript</category>
    </item>
    <item>
      <title>Cursor Wrapped</title>
      <link>https://russ.dev/posts/cursor-wrapped</link>
      <guid isPermaLink="true">https://russ.dev/posts/cursor-wrapped</guid>
      <description>A Spotify Wrapped-style dashboard for your Cursor usage: tokens, costs, favourite models, streaks, and shareable cards, built in a weekend with AI.</description>
      <pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>AI-Assisted Development</category>
      <category>Data Visualization</category>
      <category>Developer Tools</category>
    </item>
    <item>
      <title>Secret Santa</title>
      <link>https://russ.dev/posts/santa</link>
      <guid isPermaLink="true">https://russ.dev/posts/santa</guid>
      <description>Building a Secret Santa organiser with exclusion constraints and shareable links: from JWT-in-URL assignments to a Lambda and DynamoDB backend.</description>
      <pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>AWS</category>
      <category>AI-Assisted Development</category>
      <category>TypeScript</category>
    </item>
    <item>
      <title>Spoticover: Generative Spotify Playlist Covers</title>
      <link>https://russ.dev/posts/spoticover</link>
      <guid isPermaLink="true">https://russ.dev/posts/spoticover</guid>
      <description>Generating Spotify playlist covers with constrained randomness: colour-harmony rules, seeded generation, and one-try Spotify OAuth built mostly with AI.</description>
      <pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>Web Platform APIs</category>
      <category>AI-Assisted Development</category>
      <category>TypeScript</category>
    </item>
    <item>
      <title>Homelab 2025: Lessons in Redundancy</title>
      <link>https://russ.dev/posts/homelab-2025</link>
      <guid isPermaLink="true">https://russ.dev/posts/homelab-2025</guid>
      <description>Losing 50TB to a RaidZ1 mistake, rebuilding on RaidZ2, and expanding to two nodes: hard-won homelab lessons in ZFS redundancy and failure modes.</description>
      <pubDate>Fri, 05 Dec 2025 00:00:00 GMT</pubDate>
      <category>Homelab</category>
      <category>ZFS / Storage</category>
      <category>Kubernetes</category>
    </item>
    <item>
      <title>TerribleHack 2025</title>
      <link>https://russ.dev/posts/terrible25</link>
      <guid isPermaLink="true">https://russ.dev/posts/terrible25</guid>
      <description>Running TerribleHack 2025 solo for the first time: print disasters, 17 gloriously terrible projects, and a denim trophy the winners tear apart.</description>
      <pubDate>Sat, 01 Nov 2025 00:00:00 GMT</pubDate>
      <category>Hackathon</category>
      <category>Hardware / Maker</category>
      <category>Career &amp; Craft</category>
    </item>
    <item>
      <title>ETHGlobal NYC: HouseHodl</title>
      <link>https://russ.dev/posts/ethglobal-nyc</link>
      <guid isPermaLink="true">https://russ.dev/posts/ethglobal-nyc</guid>
      <description>Flying to ETHGlobal NYC after winning Web3NZ: building HouseHodl, a trustless shared-expenses app, why cross-chain broke, and napping on the venue floor.</description>
      <pubDate>Fri, 01 Aug 2025 00:00:00 GMT</pubDate>
      <category>Web3</category>
      <category>DeFi</category>
      <category>Solidity</category>
      <category>Hackathon</category>
    </item>
    <item>
      <title>LoanMarket - Web3 Hackathon 2025</title>
      <link>https://russ.dev/posts/loanmarket</link>
      <guid isPermaLink="true">https://russ.dev/posts/loanmarket</guid>
      <description>How a team of Web3 first-timers built LoanMarket in 18 hours, sharing one KYC verification across lenders with verifiable credentials, and won best overall.</description>
      <pubDate>Sat, 01 Mar 2025 00:00:00 GMT</pubDate>
      <category>Web3</category>
      <category>Solidity</category>
      <category>React</category>
      <category>Hackathon</category>
    </item>
    <item>
      <title>TerribleHack 2024</title>
      <link>https://russ.dev/posts/terrible24</link>
      <guid isPermaLink="true">https://russ.dev/posts/terrible24</guid>
      <description>Co-organising TerribleHack 2024 as Zac hands over the reins: destroy-your-project challenges, ice-cutlery dinners, and what makes a great maker event.</description>
      <pubDate>Fri, 01 Nov 2024 00:00:00 GMT</pubDate>
      <category>Hackathon</category>
      <category>Hardware / Maker</category>
      <category>Career &amp; Craft</category>
    </item>
    <item>
      <title>Rent Racket</title>
      <link>https://russ.dev/posts/rent-racket</link>
      <guid isPermaLink="true">https://russ.dev/posts/rent-racket</guid>
      <description>Designing Rent Racket, a political landlord-satire card game, at Kiwijam &apos;24: fast paper prototyping, tuning the rules, and laser-cutting the final set.</description>
      <pubDate>Fri, 01 Nov 2024 00:00:00 GMT</pubDate>
      <category>Game Dev</category>
      <category>Hackathon</category>
      <category>Hardware / Maker</category>
    </item>
    <item>
      <title>TrueNAS Migration</title>
      <link>https://russ.dev/posts/truenas</link>
      <guid isPermaLink="true">https://russ.dev/posts/truenas</guid>
      <description>Migrating a homelab from Unraid and Docker to TrueNAS Scale and Kubernetes: multiple storage classes, ZFS redundancy, GPU passthrough, and K3s in nspawn.</description>
      <pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate>
      <category>Homelab</category>
      <category>Kubernetes</category>
      <category>ZFS / Storage</category>
    </item>
    <item>
      <title>Mixer Mayhem</title>
      <link>https://russ.dev/posts/mixer-mayhem</link>
      <guid isPermaLink="true">https://russ.dev/posts/mixer-mayhem</guid>
      <description>Building a crowd-controlled robotic bartender at TerribleHack 2023: peristaltic pumps, a WebSocket god-client deploy pattern, and a force-push disaster.</description>
      <pubDate>Wed, 01 Nov 2023 00:00:00 GMT</pubDate>
      <category>Hardware / Maker</category>
      <category>AWS</category>
      <category>Web Platform APIs</category>
      <category>Hackathon</category>
    </item>
    <item>
      <title>InfraNZ</title>
      <link>https://russ.dev/posts/infranz</link>
      <guid isPermaLink="true">https://russ.dev/posts/infranz</guid>
      <description>Building InfraNZ at GovHack 2023: a 3D GIS map of Auckland&apos;s hidden public infrastructure with DeckGL, council open data, and a Rust outage API.</description>
      <pubDate>Sun, 20 Aug 2023 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>Open Data / GIS</category>
      <category>Rust</category>
      <category>Hackathon</category>
    </item>
    <item>
      <title>Bustle: A Rewards Program for Public Transport</title>
      <link>https://russ.dev/posts/bustle</link>
      <guid isPermaLink="true">https://russ.dev/posts/bustle</guid>
      <description>Bustle, a GovHack 2022 concept: a loyalty and gamification layer for Auckland public transport, mapping congestion and carbon with open transit data.</description>
      <pubDate>Thu, 01 Sep 2022 00:00:00 GMT</pubDate>
      <category>React</category>
      <category>Open Data / GIS</category>
      <category>Hackathon</category>
    </item>
    <item>
      <title>CNC Tattoo</title>
      <link>https://russ.dev/posts/cnctattoo</link>
      <guid isPermaLink="true">https://russ.dev/posts/cnctattoo</guid>
      <description>Turning a 3D printer into a CNC tattoo machine at the first Terrible Ideas Hackathon: G-code, arm-probing failures, and spring-loading a tattoo gun.</description>
      <pubDate>Fri, 01 Jul 2022 00:00:00 GMT</pubDate>
      <category>Hardware / Maker</category>
      <category>Hackathon</category>
      <category>Python</category>
    </item>
  </channel>
</rss>
