docs: add Phase 11 (self-hosted deps) and ADR-005 for HTMX/Hyperscript vendoring

Document why HTMX and Hyperscript are self-hosted instead of CDN-loaded:
zero external SPOF, faster same-origin loading, reduced CSP surface,
and controlled version upgrades.
This commit is contained in:
juanatsap
2026-05-14 13:06:20 +01:00
parent 8f4d0e9433
commit 37ef0648d7
2 changed files with 113 additions and 1 deletions
+68 -1
View File
@@ -1434,7 +1434,8 @@ end
| **v2.0** | Phase 5 | Hyperscript zoom control | -343 lines |
| **v2.1** | Phase 6 | Scroll & print + organization | -87 lines |
| **v2.2** | Phase 9 | CSS Bundling (Lightning CSS) | N/A (CSS optimization) |
| **Current** | v2.2 | Phase 9 Complete | **-715 JS lines + 54% CSS reduction** |
| **v2.3** | Phase 11 | Self-hosted HTMX & Hyperscript | 0 lines (reliability + perf) |
| **Current** | v2.3 | Phase 11 Complete | **-715 JS lines + 54% CSS reduction + zero CDN deps** |
---
@@ -1475,10 +1476,19 @@ end
-**Mobile FAB overflow fix** (responsive buttons on 375px screens)
-**Pre-push lint hook** catches CI issues before push
### Phase 11 Achievements (Self-Hosted Dependencies):
-**HTMX 1.9.10 → 2.0.10** (major version upgrade, all attributes compatible)
-**Hyperscript 0.9.14 → 0.9.91** (latest stable)
-**Zero CDN dependencies** for core libraries (HTMX + Hyperscript served locally)
-**Removed unpkg.com from CSP** (smaller attack surface)
-**No external SPOF** (site functions fully even if CDNs are down)
-**Faster loading** (no DNS lookup, TLS handshake, or redirect chains for core libs)
### Cumulative Achievements:
-**715 lines of JavaScript eliminated total** (74.9% reduction)
-**54% CSS size reduction** in production (Lightning CSS bundling)
-**96% fewer CSS HTTP requests** in production (27 → 1)
-**Zero CDN dependencies** for core libraries (HTMX + Hyperscript self-hosted)
-**All modern features preserved** (no functionality loss)
-**Improved maintainability** (organized external functions)
-**Better performance** (hardware acceleration, reduced event loop blocking)
@@ -1486,6 +1496,7 @@ end
-**Smaller bundle size** (~35KB → ~15KB JavaScript, 188KB → 86KB CSS)
-**Clean HTML templates** (no long inline hyperscript blocks)
-**Professional code organization** (separated concerns)
-**Reduced CSP attack surface** (removed unpkg.com from script-src)
---
@@ -1590,6 +1601,62 @@ expect(iphone13Mini.overflow).toBe(false);
---
## 🚀 Phase 11: Self-Hosted Dependencies - Zero CDN for Core Libraries (COMPLETED)
### 13. Self-Hosted HTMX & Hyperscript - Eliminating External SPOFs
**Problem:** HTMX (1.9.10) and Hyperscript (0.9.14) were loaded from unpkg.com CDN. This created two risks:
- **Availability**: If unpkg.com goes down, the entire site loses interactivity
- **Performance**: Each CDN resource requires DNS lookup + TLS handshake + potential redirect chains
- **Version drift**: HTMX 1.9.10 was two major versions behind (2.0.10 current)
**Solution:** Vendor both libraries locally and serve them from the same origin as the site.
#### Before (CDN):
```html
<script src="https://unpkg.com/htmx.org@1.9.10"
integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
crossorigin="anonymous"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.14"></script>
```
#### After (Self-hosted):
```html
<script src="/static/htmx/htmx.min.js"></script>
<script src="/static/hyperscript/_hyperscript.min.js"></script>
```
#### Why Self-Hosting Wins for This Project:
| Factor | CDN | Self-Hosted |
|--------|-----|-------------|
| **Availability** | Depends on unpkg.com | Same uptime as your site |
| **Latency** | DNS + TLS + redirect | Already connected (same origin) |
| **CSP surface** | Must whitelist `unpkg.com` | No external script domains needed |
| **Version control** | URL-visible, easy to forget | Explicit file, tracked in docs |
| **Cache behavior** | Shared CDN cache (maybe hit) | Guaranteed cache with your assets |
| **HTMX 2.0 upgrade** | Just change URL | Download + test (but you control timing) |
#### CSP Impact:
```go
// Before
"script-src 'self' 'unsafe-inline' https://unpkg.com https://cdn.jsdelivr.net ..."
// After — one fewer external domain
"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net ..."
```
#### Breaking Changes Check (HTMX 1.9 → 2.0):
All `hx-*` attributes used in this project (`hx-post`, `hx-get`, `hx-target`, `hx-swap`, `hx-indicator`, `hx-request`, `hx-push-url`, `hx-swap-oob`, `hx-headers`, `hx-head`) are fully supported in HTMX 2.0. The `hx-head` attribute (used for language switch SEO meta updates) moved from extension to built-in — a bonus.
#### Maintenance Note:
Self-hosted libraries require manual version tracking. Current versions:
- **HTMX**: 2.0.10 (`static/htmx/htmx.min.js`, 51KB)
- **Hyperscript**: 0.9.91 (`static/hyperscript/_hyperscript.min.js`, 172KB)
- **Iconify**: 2.1.0 (still on jsdelivr CDN — icon rendering library, acceptable external dep)
---
## 🚀 Phase 7-8: Smooth Toggle Animations - Pure Client-Side Pattern (COMPLETED)
### 9. HTMX `hx-swap="none"` + Inline Hyperscript - Client-First Toggles
+45
View File
@@ -8,6 +8,7 @@ This document records key architectural decisions made for this project.
- [ADR-002: Static Dates Instead of Git Integration](#adr-002-static-dates-instead-of-git-integration)
- [ADR-003: CI/CD with GitHub Actions](#adr-003-cicd-with-github-actions)
- [ADR-004: Application-Level Data Caching](#adr-004-application-level-data-caching)
- [ADR-005: Self-Hosted Frontend Dependencies](#adr-005-self-hosted-frontend-dependencies)
---
@@ -215,6 +216,50 @@ See [23-DATA-CACHE.md](23-DATA-CACHE.md) for complete API reference and usage pa
---
## ADR-005: Self-Hosted Frontend Dependencies
**Status:** Accepted
**Date:** 2026-05-14
### Context
HTMX (1.9.10) and Hyperscript (0.9.14) were loaded from the unpkg.com CDN. This introduced a single point of failure — if unpkg goes down, the site loses all interactivity. Additionally, each CDN request adds DNS resolution, TLS negotiation, and potential redirect overhead. HTMX 1.9.10 was also two major versions behind the current 2.0.10 release.
### Decision
**Self-host HTMX and Hyperscript as vendored files. Remove unpkg.com from the Content Security Policy.**
- `static/htmx/htmx.min.js` — HTMX 2.0.10 (51KB)
- `static/hyperscript/_hyperscript.min.js` — Hyperscript 0.9.91 (172KB)
- Iconify remains on jsdelivr CDN (icon rendering, acceptable external dependency)
### Rationale
1. **No external SPOF**: The site functions fully even if all CDNs are down
2. **Faster loading**: Same-origin assets skip DNS lookup and TLS handshake
3. **Smaller CSP surface**: `unpkg.com` removed from `script-src` whitelist
4. **Version upgrade**: HTMX 1.9.10 → 2.0.10 with zero breaking changes (all `hx-*` attributes are compatible; `hx-head` moved from extension to built-in)
5. **Cache alignment**: Libraries cached alongside the site's own assets
### Consequences
- **Positive:**
- Zero dependency on unpkg.com availability
- Reduced CSP attack surface
- HTMX 2.0 features available (built-in head support)
- Faster page loads (no cross-origin requests for core libs)
- **Considerations:**
- Version updates require manually downloading new files
- Must track current versions in documentation
- File sizes add ~223KB to the repository (acceptable trade-off)
### Documentation
See [02-MODERN-WEB-TECHNIQUES.md](02-MODERN-WEB-TECHNIQUES.md) Phase 11 for implementation details.
---
## How to Add New Decisions
When making significant architectural decisions, add a new section following this template: