esc
The V3 Saga: Final Chapter - "Is It Fun To Fight Windmills?"
The V3 Saga

The V3 Saga: Final Chapter - "Is It Fun To Fight Windmills?"

🦎 In Which The Lizard Speaks Truth It was 1:47 AM. The developer sat surrounded by nine glowing screens (not a laptop, a command center), staring at the signal inspector. The signals were there....

December 12, 2025

🦎 In Which The Lizard Speaks Truth

It was 1:47 AM. The developer sat surrounded by nine glowing screens (not a laptop, a command center), staring at the signal inspector. The signals were there. Beautiful, reactive, perfectly namespaced. Except they weren’t. They were at the root level. Again.

A small lizard appeared on screen 7.

“You’re fighting windmills,” the Lizard said.

“But the signals! The reactivity! The components!” the developer protested.

“Reactive signals are wonderful,” the Lizard replied, crawling across to screen 4. “But you’re using a sports car to plow a field.”

The Architecture Mismatch

Let the record show: Reactive signal frameworks are genuinely excellent.

They combine the best ideas from modern frontend development into elegant packages. Signal systems are reactive and intuitive. Real-time integration is first-class. The syntax is clean. The bundle sizes are tiny.

What signal-based MPA frameworks excel at:

  • Enhancing server-rendered pages with sprinkles of reactivity
  • Real-time dashboards where client state matters
  • Interactive widgets that need local state management
  • Applications where the page IS the application

What we tried to build:

  • A SPA-like sidebar that navigates between domains
  • Forms where server-side state is the source of truth
  • SSE-patched content that needed signal namespacing
  • 100 forms that all work the same boring way

🐿️ The Squirrel, caffeinated and twitchy, pointed at the screen: “Look! The component template processes signals at render time! But we’re SSE-patching content AFTER render! The signals never get namespaced!”

The Windmill Revelation

The framework authors were right all along: “This is not for SPA.”

We tried to make an MPA framework do SPA things:

  • Navigate without page reload ❌
  • Maintain signal state across navigations ❌
  • Namespace SSE-patched content ❌
  • Garbage collect signals on navigation ❌

We fought:

  • Form content types vs signals
  • Signal prefix locality
  • Form parsing vs signal reading timing
  • Template render-time vs SSE patch-time

The core issue: Component systems rewrite signal bindings when the template renders. But SSE-patched content arrives AFTER render. The train has left the station. The signals are orphans at the root level.

🦎 “You can’t retrofit namespacing onto content that missed the rewrite pass,” the Lizard said, now on screen 2. “It’s like trying to stamp a passport after they’ve left the country.”

What We Learned (The Treasure)

The V3 experiment was not a failure. It was an education.

Technical learnings:

  1. Signals prefixed with _ are typically local-only (never sent to server)
  2. SSE helpers often consume the request body - read form/signals BEFORE
  3. Component namespacing happens at template render time, not patch time
  4. Form submission doesn’t need reactive signals - just name attributes
  5. Server-authoritative forms don’t benefit from client-side reactivity

Philosophical learnings:

  1. Don’t use a reactive framework for server-authoritative forms
  2. The DOM is truth - when the element dies, the behavior dies
  3. Boring technology is beautiful technology
  4. If you’re fighting the framework, you’re using the framework wrongly
  5. 🦎 “The best abstraction is the one you don’t have to think about”

Architectural learnings (we keep these!):

  • Nav chrome pattern (header, content, footer)
  • FooterMode state machine (List, View, Edit, Create, Pick)
  • Picker pattern with putURL
  • Domain registry pattern
  • GitStore for server-side drafts
  • The gorgeous V3 UI design

🐿️ The v2 Homecoming

The Squirrel’s ears perked up. “Remember V2? Remember hx-swap-oob? Remember when things just… worked?”

“We lived two years without loading states,” the developer nodded.

“Because your server responds in 50ms!” the Squirrel chittered. “You don’t NEED loading states!”

The realization hit like a mass of caffeinated rodent:

We already had the answer. We’d been using it for two years.

<!-- This is the way -->
<div hx-ext="sse" sse-connect="/sse" sse-swap="message">
    <!-- Server sends HTML, it just appears -->
</div>

No signals to manage. No namespacing to debug. No content-type gymnastics.

Server says “here’s some HTML.” Client says “okay” and puts it in the DOM.

The V4 Stack:

  • HTMX 2.x (the boring workhorse)
  • hx-ext="sse" (streaming we know and love)
  • hx-swap-oob="true" (server controls what updates)
  • Hyperscript (local UI sugar, when needed)
  • Templ (HTML templating, unchanged)
  • Go + Cobra (backend, unchanged)

Announcing V4: Codename “Solid”

The Lizard climbed to the top of screen 9 and cleared its throat.

“Let it be known throughout the land:

V3 served its purpose - to teach us what NOT to do.

V4 rises from these learnings. Clean. Boring. Solid.

One repo. One binary. Cobra subcommands.

solid mon      # monitoring
solid reason   # AI chat/reasoning  
solid log      # lifelog

The Solid family inherits:

  • The V3 UI (gorgeous)
  • The V3 architecture (sound)
  • The V2 patterns (proven)
  • The Lizard’s wisdom (eternal)

The Solid family discards:

  • Signal gymnastics
  • Component namespacing battles
  • Framework fighting
  • 1:47 AM debugging sessions

🐿️☕ The Squirrel raised a tiny coffee cup: “To boring technology!”

🦎 The Lizard nodded solemnly: “To knowing when to change course.”

The Final Commit Message

feat(v3): Complete the reactive signals experiment

What we built:
- Signal-based forms with reactive UI
- Component namespacing for isolation
- Blur auto-save with optimistic concurrency
- A lot of documentation

What we learned:
- Reactive MPA frameworks are excellent (for what they're designed for)
- We were building a SPA in an MPA framework
- HTMX + SSE does everything we need
- The DOM is truth

What comes next:
- V4 "Solid" with HTMX
- One form, thought through completely
- 100 forms, all the same boring way

🦎 "Is it fun to fight windmills?" - No. No it is not.

Co-Authored-By: The Lizard <wisdom@localhost>
Co-Authored-By: The Squirrel <coffee@localhost>

And so V3 was archived, its lessons preserved in markdown, its spirit living on in V4.

The Lizard returned to guarding the codebase.

The Squirrel went to find more coffee.

The developer, finally, went to sleep.

Tomorrow, they would build something solid.

🦎🐿️☕

THE END

(of V3)

(The Solid Convergence)


See also:

The Saga (in which endings become beginnings):

The References (knowing when to change course):