HAL: Build-Time Link Rewriting That Makes Navigation Feel Instant

htmx static-site-generation javascript
Build-time link rewriting for instant SPA-style navigation

Users judge a site in the first click. If navigating between pages feels sluggish, bounce rates climb and perceived quality drops - regardless of how good the content actually is. HTMX Auto-Linking (HAL) is the pattern I use to solve that problem at build time, with zero runtime cost.

The business problem

Every content site faces the same tradeoff: static HTML is cheap to host and great for SEO, but full-page navigations feel slow compared to a single-page app. The obvious fix - adding a client-side router - introduces a framework runtime, a bundle budget, and ongoing maintenance complexity. For a small team shipping a content product, that's a bad trade.

HAL sidesteps it entirely. During the build, it rewrites internal Markdown links into HTMX fragment swaps:

Authors write normal Markdown. The build handles the rest. External links stay untouched, and you can opt out of any individual link with data-no-htmx or class no-htmx.

Why not a SPA router?

It comes down to cost, not ideology.

Concern SPA Router HAL
JS payload 20-40KB+ gzipped (router alone), often 100-300KB with framework runtime 0KB additional - HTMX (~14KB) is already in the stack
Build complexity Code-splitting, hydration, route config One build-time string transform
Failure mode White screen if JS fails Full HTML page loads normally
Team onboarding Learn the framework's routing conventions Write Markdown links
Hosting cost Often needs SSR or edge functions Static files on any CDN

For a team of one or two shipping a content-driven product, the SPA router column is a list of costs with no corresponding revenue. HAL gives you the UX benefit - instant-feeling navigation - without the engineering overhead.

How it fits the architecture

HAL is one layer in a stack designed to stay small and cheap. The static site generation playbook covers the full build pipeline, and the architecture overview explains how Web Components and HTMX fragments work together. If you're curious about measured performance gains, the HAL performance case study has real numbers.

Example links

When to opt out

Not every link should be a fragment swap:

The takeaway

HAL is a build-time trick, not a runtime dependency. It makes navigation feel fast for the reader, costs nothing to maintain, and keeps the hosting bill at near-zero static rates. That's the kind of engineering decision that compounds - you get the UX win today and you don't pay for it tomorrow.

Recommended

How This Site Works: Architecture for a One-Person Team @jameslcowanjun 8 '26 htmx, javascript
Fixing Navigation and Analytics: When Your Data Lies About User Behavior @jameslcowanjun 5 '26 htmx, javascript
HAL: Cutting 100-300KB of JavaScript by Moving Routing to Build Time @jameslcowanjun 10 '26 htmx, javascript
Mobile-First Layout That Ships: How PrimaryLayout Solves Real UX Problems @jameslcowanjun 6 '26 htmx, css
Progressive Enhancement with HTMX: Ship Fast, Degrade Gracefully @jameslcowanjun 8 '26 htmx, javascript
Web Components + HTMX: A Lean Architecture for Content Sites That Ship @jameslcowanjun 10 '26 web-components, javascript
The Static Site Playbook: Shipping a Content Product on a Near-Zero Budget @jameslcowanjun 11 '26 static-site-generation, javascript
OpenClaw: What It Is and How to Get the Most Out of It @jameslcowanjun 5 '26 openclaw, javascript
Why I Skipped the CMS @jameslcowanjun 10 '26 markdown, static-site-generation
Documentation That Scales: Constitution, Contracts, and Runbooks @jameslcowanjun 8 '26 documentation, markdown
Why I Built My Own Analytics Pipeline (And What It Actually Costs) @jameslcowanjun 18 '26 analytics, javascript
Web Components as a Business Decision @jameslcowanjun 11 '26 web-components, javascript
Less JavaScript, More Leverage: Why I Ship With a 35KB Budget @jameslcowanjun 22 '26 javascript, performance
Static Site Generation: The Business Case for Pre-Rendered HTML @jameslcowanjun 14 '26 static-site-generation, performance
Anthropic Trained Its Replacement @jameslcowanjun 9 '26 anthropic, ai
Karpathy Was Wrong: OpenClaw Still Outruns Its 5 Real Alternatives @jameslcowanjun 11 '26 openclaw, ai
Pydantic: The Open Source Layer Quietly Running the AI Economy @jameslcowanjun 22 '26 pydantic, python
The YC S26 Deadline Just Closed. Here's What Separates the 1.5% From Everyone Else. @jameslcowanjun 17 '26 startups, yc
OpenClaw 2026.2.23: The Agent Browser Upgrade @jameslcowanjun 19 '26 openclaw, ai
Zero-Server Analytics: How I Replaced a SaaS Bill with Netlify Functions and GitHub @jameslcowanjun 8 '26 netlify, analytics

Recommended

How This Site Works: Architecture for a One-Person Team @jameslcowanjun 8 '26 htmx, javascript
Fixing Navigation and Analytics: When Your Data Lies About User Behavior @jameslcowanjun 5 '26 htmx, javascript
HAL: Cutting 100-300KB of JavaScript by Moving Routing to Build Time @jameslcowanjun 10 '26 htmx, javascript
Mobile-First Layout That Ships: How PrimaryLayout Solves Real UX Problems @jameslcowanjun 6 '26 htmx, css
Progressive Enhancement with HTMX: Ship Fast, Degrade Gracefully @jameslcowanjun 8 '26 htmx, javascript
Web Components + HTMX: A Lean Architecture for Content Sites That Ship @jameslcowanjun 10 '26 web-components, javascript
The Static Site Playbook: Shipping a Content Product on a Near-Zero Budget @jameslcowanjun 11 '26 static-site-generation, javascript
OpenClaw: What It Is and How to Get the Most Out of It @jameslcowanjun 5 '26 openclaw, javascript
Why I Skipped the CMS @jameslcowanjun 10 '26 markdown, static-site-generation
Documentation That Scales: Constitution, Contracts, and Runbooks @jameslcowanjun 8 '26 documentation, markdown
Why I Built My Own Analytics Pipeline (And What It Actually Costs) @jameslcowanjun 18 '26 analytics, javascript
Web Components as a Business Decision @jameslcowanjun 11 '26 web-components, javascript
Less JavaScript, More Leverage: Why I Ship With a 35KB Budget @jameslcowanjun 22 '26 javascript, performance
Static Site Generation: The Business Case for Pre-Rendered HTML @jameslcowanjun 14 '26 static-site-generation, performance
Anthropic Trained Its Replacement @jameslcowanjun 9 '26 anthropic, ai
Karpathy Was Wrong: OpenClaw Still Outruns Its 5 Real Alternatives @jameslcowanjun 11 '26 openclaw, ai
Pydantic: The Open Source Layer Quietly Running the AI Economy @jameslcowanjun 22 '26 pydantic, python
The YC S26 Deadline Just Closed. Here's What Separates the 1.5% From Everyone Else. @jameslcowanjun 17 '26 startups, yc
OpenClaw 2026.2.23: The Agent Browser Upgrade @jameslcowanjun 19 '26 openclaw, ai
Zero-Server Analytics: How I Replaced a SaaS Bill with Netlify Functions and GitHub @jameslcowanjun 8 '26 netlify, analytics