zero-build-frontend
Zero-build frontend development enables production-quality web applications without bundlers or build tools. Use this skill when building static web apps, Leaflet maps, browser extensions, or integrating external data sources like Google Sheets. Covers three approaches: React via esm.sh for component-heavy SPAs, htmx for server-rendered CRUD apps, and Alpine.js for light interactivity on mostly-static pages, with patterns for mixing frameworks and managing dependencies through ESM import maps.
git clone --depth 1 https://github.com/jamditis/claude-skills-journalism /tmp/zero-build-frontend && cp -r /tmp/zero-build-frontend/dev-toolkit/skills/zero-build-frontend ~/.claude/skills/zero-build-frontendSKILL.md
# Zero-build frontend development
Patterns for building production-quality web applications without build tools, bundlers, or complex toolchains.
## Picking a stack
Three current zero-build approaches, each with different trade-offs:
| Stack | When | Bundle size impact |
|---|---|---|
| **React via esm.sh + htm** | Component-heavy SPAs, existing React mental model, Tailwind styling | ~50 KB gzipped (React + ReactDOM + htm) |
| **htmx 2.x + server-rendered HTML** | CRUD apps, traditional MPA flow, want server-side state of truth | ~14 KB gzipped (htmx alone) |
| **Alpine.js 3.x + plain HTML** | Light interactivity sprinkled into mostly-static pages, no full SPA | ~15 KB gzipped (Alpine alone) |
You can mix htmx and Alpine.js in the same page — htmx handles server interactions, Alpine handles client-side UI state. Many production sites converge on this combo.
## ESM import maps
Import maps let you write `import x from 'react'` in a `<script type="module">` without a bundler — the browser resolves the bare specifier against the map. Stable in all major browsers since 2023.
```html
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@19.0.0",
"react-dom/client": "https://esm.sh/react-dom@19.0.0/client",
"lodash-es": "https://esm.sh/lodash-es@4.17.21",
"@my-app/": "/src/"
},
"scopes": {
"https://esm.sh/": {
"scheduler": "https://esm.sh/scheduler@0.23.0"
}
}
}
</script>
```
The `scopes` block lets a sub-tree of imports resolve differently. Useful when one CDN package needs a specific transitive dependency. The trailing `/` form (`"@my-app/": "/src/"`) lets you import any file under that prefix.
**Pin versions in production.** `esm.sh/react` (without a version) and `esm.sh/react@latest` resolve at request time and can shift under you. Use exact pinned versions or SHA-locked URLs.
## htmx 2.x — server-rendered interactivity
htmx 2.0 (released June 2024) lets you add AJAX, WebSockets, and SSE to plain HTML through `hx-*` attributes. The server sends HTML fragments; the client swaps them in. No JS framework required.
```html
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
<!-- Click button → POST to server → swap response into #result -->
<button hx-post="/api/clicked" hx-target="#result" hx-swap="innerHTML">
Click me
</button>
<div id="result"></div>
<!-- Search-as-you-type with debounce -->
<input
type="search"
name="q"
hx-get="/api/search"
hx-trigger="input changed delay:300ms"
hx-target="#results"
/>
<div id="results"></div>
<!-- Infinite scroll -->
<div hx-get="/api/items?page=2"
hx-trigger="revealed"
hx-swap="afterend">
...
</div>
```
htmx 2.x dropped IE support and tightened the API; if you're on htmx 1.x and don't need to migrate, 1.x still receives security patches. New code should target 2.x.
## Alpine.js 3.x — client-side reactivity in HTML
Alpine.js (current 3.14+) is a minimal alternative to Vue/React for sprinkles of interactivity. State and behavior live as `x-*` attributes in the markup.
```html
<script defer src="https://unpkg.com/alpinejs@3.14.1/dist/cdn.min.js"></script>
<!-- Toggle visibility -->
<div x-data="{ open: false }">
<button @click="open = !open">Toggle</button>
<div x-show="open" x-transition>Content here</div>
</div>
<!-- Two-way binding + computed -->
<div x-data="{ first: '', last: '' }">
<input x-model="first" placeholder="First">
<input x-model="last" placeholder="Last">
<p x-text="`Hello, ${first} ${last}`"></p>
</div>
<!-- Fetch on mount -->
<div x-data="{ items: [] }"
x-init="items = await (await fetch('/api/items')).json()">
<template x-for="item in items" :key="item.id">
<li x-text="item.title"></li>
</template>
</div>
```
Alpine pairs naturally with htmx: htmx swaps a server-rendered fragment in, Alpine handles whatever client-side state that fragment needs (open/close, optimistic toggles, form validation).
## React via CDN (esm.sh)
### Basic setup
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zero-Build React App</title>
<!-- Tailwind CSS via CDN.
cdn.tailwindcss.com is the Play CDN; Tailwind explicitly recommends
it for prototyping only — it ships an in-browser JIT compiler that
runs at every page load. For production, use the standalone CLI
binary or the Vite/PostCSS plugin. Tailwind 4 (released Jan 2025)
is the current major; the Play CDN serves v3 by default. -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
display: ['Special Elite', 'monospace'],
body: ['Roboto Mono', 'monospace'],
},
colors: {
brand: {
primary: '#2dc8d2',
secondary: '#f34213',
dark: '#183642',
}
}
}
}
}
</script>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Special+Elite&family=Roboto+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<!-- Custom styles -->
<link rel="stylesheet" href="index.css">
</head>
<body>
<div id="root"></div>
<!-- ES Module imports.
React 19 (Dec 2024) is the current major; 18.x still works fine
for sites that pin to it. Pin a specific version in production —
don't ship `react@latest`, since esm.sh resolves at request time. -->
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@19.0.0",
"react-dom/client": "https://esm.sh/react-dom@19.0.0/client",
"htm": "https://esm.sh/htm@3.1.1"
}
}
</script>
<script type="module" src="index.js"></script>
</body>
</html>
```
### React with htm (no JSX, no build)
```javascript
// index.js
import React, { useState, useEffect, useRef } from 'react';
import { createRoot } from 'reaWeb accessibility patterns for news sites, journalism tools, and academic platforms. Use when building accessible interfaces, auditing existing sites for WCAG compliance, writing alt text for news images, creating accessible data visualizations, or ensuring content reaches all readers including those using assistive technologies. Essential for newsroom developers and anyone publishing web content.
Electron desktop application development with React, TypeScript, and Vite. Use when building desktop apps, implementing IPC communication, managing windows/tray, handling PTY terminals, integrating WebRTC/audio, or packaging with electron-builder. Covers patterns from AudioBash, Yap, and Pisscord projects.
Remote JavaScript console access and debugging on mobile devices. Use when debugging web pages on phones/tablets, accessing console errors without desktop DevTools, testing responsive designs on real devices, or diagnosing mobile-specific issues. Covers Eruda, vConsole, Chrome/Safari remote debugging, and cloud testing platforms.
Use this skill when creating new files that represent architectural decisions — data models, infrastructure configs, auth boundaries, API contracts, CI/CD pipelines, or event systems. Flags irreversible decisions and forces a discussion about trade-offs before committing.
Python data processing pipelines with modular architecture. Use when building content processing workflows, implementing dispatcher patterns, integrating Google Sheets/Drive APIs, or creating batch processing systems. Covers patterns from rosen-scraper, image-analyzer, and social-scraper projects.
This skill should be used when the user reports a bug, describes unexpected behavior, says something is "broken", "not working", "failing", mentions an "error", "issue", or "problem" in code, or asks to "fix" something. Enforces test-driven bug fixing workflow.
Methodology for effective AI-assisted software development. Use when helping users build software with AI coding assistants, debugging AI-generated code, planning features for AI implementation, managing version control in AI workflows, or when users mention "vibe coding," Claude Code, Cursor, GitHub Copilot, Aider, Continue, Cline, Codex, Windsurf, or similar AI coding tools. Provides strategies for planning, testing, debugging, and iterating on code written with LLM assistance.
Web scraping with anti-bot bypass, content extraction, undocumented APIs and poison pill detection. Use when extracting content from websites, handling paywalls, implementing scraping cascades or processing social media. Covers requests, trafilatura, Playwright with stealth mode, yt-dlp and instaloader patterns.