Technical guide
Vite’s ?url Import Gives You a URL, Not jQuery

Writing

Technical decisions, working software, and what I learned after the documentation stopped being enough. Begin with a curated route, or choose your own path through the archive.
Trailhead
Four pieces that show the range of the journal without asking you to scan all 92 entries.
Technical guide


Technical guide

Technical guide

Mapped routes
Related notes read better together. These routes connect recurring work across years.
Running Hermes Agent against persistent infrastructure, integrations, and unattended work.
View 3 notes Route 02What framework changes cost after the upgrade guide ends.
View 6 notes Route 03Measured notes on agents, review, cost, and the work around the model.
View 6 notes Route 04Self-hosting and smart-home systems tested beyond the happy path.
View 4 notes Route 05Old platform decisions revisited with the benefit of hindsight.
View 5 notesThe full journal
Showing all 92 notes
The WP Engine fight, the Valkey fork, and agent-written code raise a harder question: what keeps an open-source project honest?

Removing SSR simplified Cubbly but delayed useful inventory. I compared four client-loading compositions and kept the one that made real route content 31–42% faster.

I removed React SSR from Cubbly because maintaining Lingui across the Worker and browser was not worth the speed it bought on a private application.

I use Hermes Agent to interpret and configure automations, then let Home Assistant or a script execute repeatable actions with visible failure states.

GPT-5.6 turns capability into a price ladder, while Codex Spark turns speed into a separate button. AI pricing is becoming part of the interface.

I wanted to keep a shared table component current without accepting migration work on faith. A side-by-side benchmark made the trade-off much easier to judge.

React Router v8 keeps the framework-mode API familiar and moves v7's future flags into defaults. That restraint matters after an expensive v6-to-v7 migration.

Closed-model guardrails remain tied to the provider, even as comparable open weights spread. Public safety needs controls that survive that reality.

Models make awkward code cheaper to replace. Review should block future risk and leave private ideas of neat to automated conventions.

Grok Build produces useful patches, but its weekly limit changes how I use it. The harness and quota now matter more than the model.

Claude Code lowers the cost of being a Rust beginner. It kept two local-hardware projects moving while I learned the language inside them.

I keep changing this blog. One small Cloudflare Worker lets the URLs survive the changes while the site itself stays static.

GLM costs a fraction of Opus per token. OpenCode's Plan/Build toggle doesn't cut that cost back down — it just moves it.

My company merged separate AI tool budgets into one shared pool. That's when Opus versus GLM stopped being an abstract question.

dns-sd exposes what smart home apps hide: Apple, Amazon, and eero each run separate Thread meshes on the same network, and devices on different meshes route through Wi-Fi instead of communicating directly.

How to group color lights in Home Assistant using Helpers — and why the old YAML platform approach stopped working in 2026.5.

Tripsy released an official CLI and MCP server in May 2026. The CLI is the better tool. Everything I documented for the SQLite approach is now unnecessary.

Papra looked healthy on my NAS while registration failed. The browser hid the useful detail: SQLite belonged to the wrong user.

I ordered a Google Fitbit Air to test whether a lighter band can solve the sleep-data gap my Apple Watch leaves.

Two environment variables and a gateway restart. I said 'turn off all my lights' and they went off two seconds later.

UGREEN said my Hermes container was running. The gateway couldn't read its config. Two user IDs explained the failure—and the fix.

Biome keeps my AI coding loop moving, but it doesn't replace TypeScript. Here is the current setup and the trade-off I kept.

Tripsy stores all your trip data in a local SQLite file that iCloud syncs to your Mac. The file is already on your disk — no export needed.

Adobe Animate kept the Flash timeline alive for HTML5, but the web moved on. Maintenance mode confirms the bridge could not hold.

I registered a San Francisco DBA for $236. It took two City Hall stops, one newspaper email, and four weeks of publication.

I expected Claude Code plugins to be heavy infrastructure. The frontend-design plugin is mostly Markdown; the marketplace makes it installable and scoped.

In Vite, ?url changes a JavaScript import into an asset URL import. Here is the fix—and when the suffix is actually useful.

jQuery 4.0.0 shipped last week. I didn't expect to write about jQuery in 2026. The project has been around since 2006.

I spent 45 minutes teaching Claude a fix I already knew. Putting that project quirk in CLAUDE.md stopped the same rediscovery next time.

Tailwind v4 rendered my shared components without their utility classes. One @source directive fixed three hours of monorepo debugging.

I tried Origin as an alternative to Copilot Money. More financial products did not make up for the transaction review it handed back to me.

Six months with React Router loaders changed my default. I add React Query only when repeated fetching, shared data, or polling gives me a reason.

I wrote in June that AI was becoming the new backdoor layoff. Companies would use "AI efficiency gains" as cover for not hiring people back.

React Compiler 1.0 moved routine rendering memoization into the build. React.memo, useCallback, and useMemo now need a specific reason.

My machine has one Claude Code executable and one updater. Here is how I check the path, remove conflicts, and keep it that way.

Meta cut 600 AI roles while still hiring for its superintelligence lab. The move shows which AI work leadership wanted to fund—and which it did not.

After using Comet for coupons, search, and summaries, I am not convinced putting an agent in the browser solves the hard part: judgment.

Claude Code on the web changes coding from an editor interaction into delegated work. That matters more than adding another interface.

Using Sora in a TikTok-style feed made social media's incentive problem hard to ignore: fabricated video is now cheaper than recording reality.

Samsung's 7-million-parameter TRM beat much larger models on specific reasoning benchmarks by revising its answer up to 16 times.

I use Claude Haiku for small refactors, review, and debugging. Its lower cost and faster responses matter more there than deeper reasoning.

I tested SwiftUI toolbar placement, grouping, search, and overflow on iPhone and iPad. The useful mental model is intent—not fixed screen coordinates.

I rebuilt SwiftUI's TabView examples to separate the iOS 18 navigation APIs from the iOS 26 Liquid Glass redesign—and to see where the system takes control.

VoiceOver read my compound views as a pile of unrelated elements. Grouping, labels, and combined accessibility testing fixed the experience.

The full Liquid Glass effect became distracting while I built with it. Here is how I handled Reduce Motion and Dynamic Type in SwiftUI.

A small Cloudflare Worker can rewrite /tag/* to /tags/* without changing the main application or dropping query strings.

I moved a static site from Cloudflare Pages to Workers in five minutes. The config was easy; deciding whether a static blog benefits is harder.

My working setup for a Home Assistant Connect ZWA-2 on a Ugreen NAS, using Docker and Z-Wave JS UI.

How I deployed the React Router application with Fly.io, Cloudflare, Neon, Docker, and migration history I could roll back.

The React Router, TypeScript, PostgreSQL, and authentication stack I chose after using LLMs to prototype the alternatives.

Cloudflare 525 errors on Fly.io usually mean the origin certificate is wrong. Fix the custom domain cert before blaming DNS.

The migration took two focused sessions: dependencies first, then 40 files of imports and route types. Typegen was the part worth keeping.

My Remix-to-React Router v7 migration touched 40 files and removed 591 net lines. Imports were easy; TypeScript took the time.

Leaving Next.js for Remix taught me why the annoying-looking use client boundary exists—and what Remix gives up without it.

My Remix app ran locally and failed on Vercel with EMFILE. The workarounds reduced file churn but could not expose or change the platform limit.

AI search is turning websites from destinations into raw material. The web may survive that transition, but human voices will be harder to find.

The court treated AI training as transformative while leaving Anthropic exposed for keeping a library of pirated books.

A new data-model entity touched several old pages. Rebuilding those UI components was faster than carrying their Flow types and old assumptions forward.

Companies can shrink teams without announcing layoffs. They call it AI efficiency, lower hiring needs, and let attrition do the rest.

The package manager was the easy part. File APIs, CI, compatibility checks, and Claude Code produced most of the migration's useful work.

Moving this blog from Node.js to Bun cut its build from 37 seconds to 20. Native file and glob APIs also removed code I no longer needed.

Windsurf removed flow action credits and cut team pricing while OpenAI acquisition talks were being reported. I cared more about the simpler bill.

Figma's dispute with Lovable over Dev Mode shows why common developer terms make weak trademarks and costly legal weapons.

OpenAI talked a ~$3B Windsurf deal. I use Claude Code and Cursor; the story that matters is who owns the IDE relationship, not the model API.

GPT-4.1's benchmark jump showed up in my Windsurf and Cursor use as cleaner diffs and fewer back-and-forth retries.

A leaked OpenAI lineup showed five models, but the mini and nano pricing mattered more to me than another flagship.

The benchmark gap was obvious, but deleting 90 lines of build configuration was the better reason to choose Vite for a modern app.

Similarweb March 2025: ChatGPT at 4.55B visits, X at 4.58B. ChatGPT grew faster that month. Infrastructure, not a toy.

Copilot shipped agent mode and more models. Microsoft also tightened extension licenses so some tools refuse to run in Cursor.

AI access is becoming another way to buy time, better service, and economic leverage. My son will grow up inside that divide.

Claude Code for hobby refactors, Cursor at work — two tools, two jobs, and where each one still breaks.

Claude Code helped build the parser, generator, templates, and Cloudflare deployment. Syntax highlighting and timezones took more work.

I paid about $10 to see whether Claude Code could scaffold the TypeScript static-site generator behind this blog. Most of its choices held up.

Replacing Assistant with Gemini fits Google's long pattern of abandoning products instead of earning trust through steady maintenance.

Public libraries give coding agents examples, documentation, and discussions they can retrieve. Private APIs must supply that context themselves.

When Chrome began disabling uBlock Origin under Manifest V3, I stopped looking for another extension and moved my browsing to Brave.

Bitcoin ATMs charge steep fees and are frequently used in scams. Their placement in vulnerable neighborhoods makes the business model hard to defend.

A personal blog should be fast on a phone and boring to host — Markdown to static HTML on Cloudflare, no app server.

OpenAI's agent tiers run $2k–$20k a month. That is not 'AI is cheap labor' pricing — it is closer to a contractor line item.

I use Perplexity for most search and for a daily news skim. Google for the stubborn queries. Apple News lost the paywall fight.

I started writing here again — web development, AI tools I actually run, and what SF startups taught me the expensive way.

Adobe barely documented custom HTML5 components in Animate CC, so I worked backward from its built-in Video component.

Lambda's clunky deployment process forced me to think small. That constraint led me to better microservices design. Sometimes friction is good.

Microsoft added Ubuntu's Bash to Windows. I tested it for real work and hit some rough edges.

The Apache module path was the easy-to-miss part of running Homebrew's PHP 5.6 on macOS El Capitan. Here is the full setup.

I worked in advertising as browsers pushed Flash out. The web gained battery life and privacy controls, while ad production got much harder.

CORS failures that look unrelated often come down to request type, duplicate headers, or credentials. Here is how the browser treats each case.

Ubuntu 16.04 ships with PHP 7, which broke my WordPress. Here's how to upgrade PHP config and point nginx to the new php-fpm socket.

Edge 14 hit 460 points on the HTML5 Test. For the first time, Microsoft's browser was competitive with Firefox. Here's what that meant for web standards.

I upgraded two repositories to Mocha v3. The migration was uneventful, and the fixed .only() behavior was reason enough to do it.

The exact S3 CORS configuration I used to make responses vary by origin instead of letting a CDN cache the wrong header.

Once I stopped supporting IE8, UglifyJS still emitted compatibility code for it. This Gulp option switched those workarounds off.

No notes match that route. Clear a filter and try another path.