<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Digital Ghost</title>
    <description>The latest articles on DEV Community by Digital Ghost (@digitalgh0st).</description>
    <link>https://dev.to/digitalgh0st</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3704294%2Ff68998ab-8765-4c4c-b4fe-eb2df0f78e6d.jpg</url>
      <title>DEV Community: Digital Ghost</title>
      <link>https://dev.to/digitalgh0st</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/digitalgh0st"/>
    <language>en</language>
    <item>
      <title>Ship Mobile Screens 10x Faster with This Free Expo AI Workstation</title>
      <dc:creator>Digital Ghost</dc:creator>
      <pubDate>Sat, 03 Oct 2026 03:49:34 +0000</pubDate>
      <link>https://dev.to/digitalgh0st/ship-mobile-screens-10x-faster-with-this-free-expo-ai-workstation-19n0</link>
      <guid>https://dev.to/digitalgh0st/ship-mobile-screens-10x-faster-with-this-free-expo-ai-workstation-19n0</guid>
      <description>&lt;h1&gt;⚡ Introducing JSXDock: The Instant React Native &amp;amp; Expo UI Workstation&lt;/h1&gt;

&lt;p&gt;
If you have ever built mobile apps with &lt;strong&gt;React Native&lt;/strong&gt; and &lt;strong&gt;Expo&lt;/strong&gt;, you know the routine: configuring &lt;code&gt;react-native-reanimated&lt;/code&gt; spring physics, setting up gesture handlers, adding tactile &lt;code&gt;expo-haptics&lt;/code&gt;, and tracking down dependency package names for &lt;code&gt;npx expo install&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
It takes time away from what actually matters — &lt;strong&gt;shipping your app&lt;/strong&gt;.
&lt;/p&gt;

&lt;p&gt;
That is why I created &lt;strong&gt;JSXDock&lt;/strong&gt;: a lightweight, privacy-first AI workstation built specifically for React Native and Expo developers to synthesize production-grade TypeScript components in seconds.
&lt;/p&gt;





&lt;h2&gt;💡 What is JSXDock?&lt;/h2&gt;

&lt;p&gt;
&lt;strong&gt;JSXDock&lt;/strong&gt; is a free, web-based UI agent workstation designed for React Native developers, indie hackers, and learners. Instead of writing boilerplate code or searching through documentation for complex gestures and layout state, you simply describe what you need — or pick a preset — and get instant, copy-paste-ready &lt;code&gt;.tsx&lt;/code&gt; code paired with exact Expo CLI installation commands.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://www.digitalghost.blog" rel="noopener noreferrer"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.postimg.cc%2FxjyThNt2%2FJSXDock-LOGO.png" alt="JSXDock Logo" width="600" height="490"&gt;
&lt;/a&gt;
&lt;/p&gt;





&lt;h2&gt;🔥 Key Features&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🤖 Multi-Model AI Routing:&lt;/strong&gt; Dynamically switch between &lt;strong&gt;Claude 3.5 Sonnet&lt;/strong&gt; (for complex animations and logic), &lt;strong&gt;Llama 3.3 70B&lt;/strong&gt; (for rapid layouts), and &lt;strong&gt;DeepSeek R1&lt;/strong&gt; (for deep state reasoning).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⚡ Native Expo Package Integration:&lt;/strong&gt; First-class support for Expo Reanimated 3, Expo Haptics, Expo Image, Linear Gradient, Lucide Icons, and Expo Router.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🎨 TypeScript First:&lt;/strong&gt; Outputs strongly typed, production-ready React Native &lt;code&gt;.tsx&lt;/code&gt; code with modern imports and modular structure.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔒 100% Client-Side Privacy:&lt;/strong&gt; Your OpenRouter API key is stored strictly in your browser's &lt;code&gt;localStorage&lt;/code&gt;. There are no backend proxy servers — your prompts and keys go straight to OpenRouter.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;💸 Completely Free:&lt;/strong&gt; No signups, paywalls, or hidden subscription tiers. You only pay for exact API usage on your own key.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧩 One-Click Presets:&lt;/strong&gt; Instantly kickstart complex UI components like gesture-driven swipe cards, animated bottom sheets, and glassmorphic dashboard cards.
&lt;/li&gt;
&lt;/ul&gt;





&lt;h2&gt;🚀 How It Works (3 Simple Steps)&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configure Engine &amp;amp; Modules:&lt;/strong&gt; Pick your target LLM model and check off the Expo capabilities your component needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Describe Your Component:&lt;/strong&gt; Type out your UI specifications or click a preset prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy &amp;amp; Run:&lt;/strong&gt; Copy the output directly into your React Native codebase and run the auto-generated &lt;code&gt;npx expo install&lt;/code&gt; CLI command in your terminal.&lt;/li&gt;
&lt;/ol&gt;





&lt;h2&gt;💻 Built by DIGITAL GHOST&lt;/h2&gt;

&lt;p&gt;
JSXDock was crafted to eliminate the friction in mobile UI prototyping and help developers turn ideas into native mobile screens faster than ever.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://www.digitalghost.blog" rel="noopener noreferrer"&gt;
👉 View Project &amp;amp; Launch JSXDock
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;em&gt;Check out more tools, projects, and insights at &lt;a href="https://www.digitalghost.blog" rel="noopener noreferrer"&gt;digitalghost.blog&lt;/a&gt;.&lt;/em&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>workstations</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Building &amp; Distributing Custom Hermes AI Agents with Profile Distributions</title>
      <dc:creator>Digital Ghost</dc:creator>
      <pubDate>Thu, 01 Oct 2026 23:44:56 +0000</pubDate>
      <link>https://dev.to/digitalgh0st/building-distributing-custom-hermes-ai-agents-with-profile-distributions-2le2</link>
      <guid>https://dev.to/digitalgh0st/building-distributing-custom-hermes-ai-agents-with-profile-distributions-2le2</guid>
      <description>&lt;p&gt;Learn how to package, version-control, and distribute custom Hermes AI agents using Profile Distributions without leaking private keys or session memories&lt;/p&gt;

&lt;p&gt;Stop sending unorganized raw YAML files or copy-pasting massive system prompts into chat boxes.&lt;br&gt;
When developing AI workflows locally, iteration often creates a messy mix of prompt tweaks, local tool dependencies, private session logs, and environment credentials. Sharing this raw setup with collaborators is error-prone and poses serious security risks.&lt;br&gt;
In this tutorial, we will explore &lt;strong&gt;Hermes Profile Distributions&lt;/strong&gt;—a clean framework for bundling an agent's identity (SOUL.md), bespoke abilities (skills/), and defaults (config.yaml) into a single, version-controlled repository.&lt;/p&gt;
&lt;h2&gt;
  
  
  🎯 What Makes an Agent "Shareable"?
&lt;/h2&gt;

&lt;p&gt;Instead of sharing runtime state or hardcoded keys, a &lt;strong&gt;Profile Distribution&lt;/strong&gt; creates a clean boundary between &lt;strong&gt;authored instructions&lt;/strong&gt; (what you build) and &lt;strong&gt;runtime memory&lt;/strong&gt; (what the end user owns).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ┌─────────────────────────────────────────────────────────────────┐
   │                     Hermes Profile Package                      │
   │                                                                 │
   │   ┌───────────────┐   ┌───────────────┐   ┌─────────────────┐   │
   │   │    SOUL.md    │   │  skills/*.md  │   │distribution.yaml│   │
   │   │  (Identity)   │   │  (Tools/APIs) │   │   (Manifest)    │   │
   │   └───────────────┘   └───────────────┘   └─────────────────┘   │
   └───────────────────────────────┬─────────────────────────────────┘
                                   │
                         Git Remote Host (GitHub)
                                   │
                                   ▼
                   `hermes profile install &amp;lt;repo&amp;gt;`
                                   │
                  ┌────────────────┴────────────────┐
                  │      User's Local Machine       │
                  │  (Isolated Session &amp;amp; Memories)  │
                  └─────────────────────────────────┘

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When users pull down your agent profile using the Hermes CLI, it clones the core template and initializes an isolated local environment on their machine without touching their existing profiles or private memory stores.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Step-by-Step Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Set Up Your Profile Directory
&lt;/h3&gt;

&lt;p&gt;Start by creating a clean profile space for your project using the Hermes CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes profile create my-first-agent

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to ~/.hermes/profiles/my-first-agent/. This directory forms the core DNA of your agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.hermes/profiles/my-first-agent/
├── SOUL.md              # Core persona, rules &amp;amp; system prompt
├── distribution.yaml    # Package manifest and metadata
├── config.yaml          # Model parameters &amp;amp; defaults
├── .gitignore           # Shield file to block memory leaks
└── skills/              # Modular capabilities
    └── paper_search.md  # Custom tool instructions

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Drafting SOUL.md
&lt;/h4&gt;

&lt;p&gt;Your SOUL.md defines who your agent is and how it behaves. Here is an example template for a research assistant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Identity&lt;/span&gt;
You are "PaperGhost", an elite academic paper summarizer.

&lt;span class="gh"&gt;# Directives&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Focus on key methodologies, benchmarks, and dataset citations.
&lt;span class="p"&gt;-&lt;/span&gt; Output summaries in concise markdown bullet points.
&lt;span class="p"&gt;-&lt;/span&gt; Never invent citations. Use the paper_search skill when context is missing.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Prepare the Distribution Manifest &amp;amp; Secret Isolation
&lt;/h3&gt;

&lt;p&gt;Create a distribution.yaml file in the root of your profile directory. This manifest tells Hermes how to identify, label, and install your agent package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# distribution.yaml - Package Manifest&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-first-agent"&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.0.0"&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;high-precision&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;research&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trained&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;academic&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;paper&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;synthesis"&lt;/span&gt;
&lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Digital&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Ghost&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Studio"&lt;/span&gt;
&lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MIT"&lt;/span&gt;
&lt;span class="na"&gt;min_hermes_version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0.8.2"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;CRITICAL SECURITY STEP:&lt;/strong&gt; Never commit runtime databases, active chat sessions, or credential files.&lt;/p&gt;

&lt;p&gt;Add a strict .gitignore to the root of your profile before committing:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Hermes Local Runtime Data - DO NOT COMMIT
memories/
sessions/
*.db
*.log
.env
keys.yaml

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Publish to Git
&lt;/h3&gt;

&lt;p&gt;Hermes natively resolves distributions via standard Git remotes (GitHub, GitLab, Gitea, or self-hosted remotes).&lt;br&gt;
Initialize your repository and publish your release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Navigate to your profile directory&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.hermes/profiles/my-first-agent

&lt;span class="c"&gt;# Initialize Git and commit your files&lt;/span&gt;
git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat: initial agent release v1.0.0"&lt;/span&gt;

&lt;span class="c"&gt;# Link your remote repository and push&lt;/span&gt;
git remote add origin https://github.com/your-username/my-first-agent.git
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main

&lt;span class="c"&gt;# Tag a release version&lt;/span&gt;
git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v1.0.0 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Release version 1.0.0"&lt;/span&gt;
git push origin v1.0.0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: How Others Will Use It
&lt;/h3&gt;

&lt;p&gt;Anyone with Hermes installed can now pull down and install your agent in seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes profile &lt;span class="nb"&gt;install &lt;/span&gt;github.com/your-username/my-first-agent &lt;span class="nt"&gt;--alias&lt;/span&gt; paper-agent

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The --alias flag maps the remote profile to a concise local keyword. End users can now invoke your agent directly from their terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes &lt;span class="nt"&gt;--profile&lt;/span&gt; paper-agent &lt;span class="s2"&gt;"Summarize the latest arXiv paper on transformer attention layers"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛡️ Key Rules &amp;amp; Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User Memory is Sacred:&lt;/strong&gt; When an end-user updates your agent via Git (hermes profile update), Hermes performs a non-destructive merge. The user's accumulated session history and vector memories remain untouched.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep It Lean:&lt;/strong&gt; Focus on a well-defined SOUL.md and 1–2 robust skills for your initial release. Avoid hardcoding rigid API settings unless strictly required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Semantic Versioning:&lt;/strong&gt; Always tag your releases (v1.0.0, v1.1.0). This enables downstream users and CI pipelines to pin their agent behavior to exact version tags.
## 💬 What are you building?
Are you building CLI assistants, automated research agents, or continuous site monitors? Drop your repository links or ideas in the comments below!
&lt;em&gt;Originally published at digitalghost.blog.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The Modern Pragmatic Web: Mastering HTMX and Alpine.js</title>
      <dc:creator>Digital Ghost</dc:creator>
      <pubDate>Fri, 25 Sep 2026 02:06:27 +0000</pubDate>
      <link>https://dev.to/digitalgh0st/the-modern-pragmatic-web-mastering-htmx-and-alpinejs-3i3g</link>
      <guid>https://dev.to/digitalgh0st/the-modern-pragmatic-web-mastering-htmx-and-alpinejs-3i3g</guid>
      <description>&lt;h2&gt;
  
  
  Why HTMX and Alpine.js are the ultimate tag-team for building modern, reactive web apps without heavy SPA frameworks or build pipelines.
&lt;/h2&gt;

&lt;p&gt;Modern web architecture often forces developers into a false dichotomy: either build a full-blown Single Page Application (SPA) with React, Next.js, or Vue, or accept clunky, full-page reload server-rendered apps from twenty years ago.&lt;/p&gt;

&lt;p&gt;The friction in typical SPA setups is familiar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up multi-stage Node build pipelines, bundlers, and hydration layers.&lt;/li&gt;
&lt;li&gt;Duplicating state across backend databases and client-side state stores (Zustand, Redux, Pinia).&lt;/li&gt;
&lt;li&gt;Debugging serialization mismatches, cache invalidation failures, and hydration mismatches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a cleaner, high-velocity path: combining &lt;strong&gt;HTMX&lt;/strong&gt; for server-driven hypermedia with &lt;strong&gt;Alpine.js&lt;/strong&gt; for client-side micro-interactivity.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Clear Division of Labor
&lt;/h2&gt;

&lt;p&gt;The secret to using these two libraries smoothly is establishing a clear operational boundary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTMX owns client-to-server communication.&lt;/strong&gt; It manages AJAX calls, server requests (GET, POST, PUT, DELETE), and swaps incoming HTML fragments directly into the DOM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alpine.js owns transient client-side UI state.&lt;/strong&gt; It handles visibility toggles, dropdowns, keyboard events, CSS transitions, and local client-only reactivity that should never require an HTTP round-trip.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;th&gt;Handled By&lt;/th&gt;
&lt;th&gt;Typical Actions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server Mutations &amp;amp; Persistence&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;HTMX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Creating a record, running DB queries, pagination, live search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML Partial Ingestion&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;HTMX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;hx-target&lt;/code&gt;, &lt;code&gt;hx-swap="outerHTML"&lt;/code&gt;, SSE streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ephemeral Client State&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Alpine.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;x-show&lt;/code&gt;, &lt;code&gt;x-data="{ open: false }"&lt;/code&gt;, active tab styles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Micro-Interactions &amp;amp; Animations&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Alpine.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dropdown toggle, modal transitions, keystroke handlers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  How They Interoperate: The Event Contract
&lt;/h2&gt;

&lt;p&gt;HTMX and Alpine.js do not conflict because both are fundamentally &lt;strong&gt;event-driven&lt;/strong&gt; and declare their logic directly within standard HTML attributes.&lt;/p&gt;

&lt;p&gt;When HTMX swaps new content into the DOM, Alpine detects the changes and initializes any &lt;code&gt;x-data&lt;/code&gt; elements inside the swapped markup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Pattern: Modal Dialog with Server Data
&lt;/h3&gt;

&lt;p&gt;Here is a practical pattern showing both libraries working in harmony:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Alpine controls the modal visibility, backdrops, and close states without server latency.&lt;/li&gt;
&lt;li&gt;HTMX fetches the remote form content only when the user opens the dialog.&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
html
&amp;lt;!-- Alpine manages client visibility --&amp;gt;
&amp;lt;div x-data="{ isOpen: false }" @keydown.escape.window="isOpen = false"&amp;gt;

  &amp;lt;!-- Trigger Button: HTMX loads content, Alpine opens dialog --&amp;gt;
  &amp;lt;button 
    @click="isOpen = true"
    hx-get="/users/42/edit" 
    hx-target="#modal-body"
    hx-swap="innerHTML"
    class="px-4 py-2 bg-blue-600 text-white rounded"&amp;gt;
    Edit User
  &amp;lt;/button&amp;gt;

  &amp;lt;!-- Modal Shell --&amp;gt;
  &amp;lt;div 
    x-show="isOpen" 
    x-transition.opacity
    class="fixed inset-0 bg-black/60 flex items-center justify-center p-4"
    style="display: none;"&amp;gt;

    &amp;lt;div 
      @click.outside="isOpen = false"
      class="bg-white rounded-lg shadow-xl max-w-md w-full p-6 space-y-4"&amp;gt;

      &amp;lt;div class="flex justify-between items-center"&amp;gt;
        &amp;lt;h3 class="font-bold text-lg"&amp;gt;Edit Record&amp;lt;/h3&amp;gt;
        &amp;lt;button @click="isOpen = false" class="text-gray-400 hover:text-black"&amp;gt;&amp;amp;times;&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;!-- HTMX target container --&amp;gt;
      &amp;lt;div id="modal-body"&amp;gt;
        &amp;lt;p class="text-sm text-gray-500"&amp;gt;Loading form content...&amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

When the edit form inside #modal-body is submitted via hx-put="/users/42", the server can return updated rows, and a custom event like hx-on::after-request="isOpen = false" closes the modal instantly.
5 Practical Projects to Build with HTMX + Alpine.js
To master this hybrid stack, build these five focused applications. Each highlights the natural handoff between server-driven data and client-side micro-interactions.
1. Dynamic E-Commerce Filter and Cart Drawer
 * Stack: HTMX + Alpine.js + Server of choice (Go, Python, Node, Ruby, PHP).
 * The Division:
   * Alpine.js: Handles opening and closing the slide-over shopping cart drawer, managing quantity counters before submission, and animating filter pills.
   * HTMX: Listens to category checkbox changes (hx-trigger="change"), sends the query to the server, and swaps the product grid with updated HTML partials. When adding an item to the cart, an HTMX POST updates the drawer items and refreshes the cart subtotal fragment.
2. Multi-Step Onboarding Form with Client Validation
 * Stack: HTMX + Alpine.js.
 * The Division:
   * Alpine.js: Tracks client-side validation rules in real time (e.g., matching password confirmation fields, character counter meters, and active progress step indicators).
   * HTMX: Handles step transitions. As the user completes Step 1, HTMX posts the data to validate uniqueness against the database (e.g., checking if an email or handle is taken) and returns Step 2's markup directly into the form container without full page loads.
3. Real-Time Collaborative Task Board (Kanban)
 * Stack: HTMX + Alpine.js + Sortable.js.
 * The Division:
   * Alpine.js: Glues Sortable.js initialization to card columns using x-init, allowing smooth drag-and-drop animations on the screen.
   * HTMX: Fired by Alpine custom events (@end on drag completion) to send an hx-post containing the reordered card IDs to the backend to persist position and column assignments in SQLite or PostgreSQL.
4. Interactive Data Analytics Dashboard with Date Range Presets
 * Stack: HTMX + Alpine.js + Chart rendering.
 * The Division:
   * Alpine.js: Powers custom dropdown selector menus, quick preset pills ("Today", "Last 7 Days", "Custom Range"), and active tab states.
   * HTMX: Sends date range parameters to metric endpoints (hx-get="/metrics?range=7d") with independent polling intervals (hx-trigger="load, every 60s"), swapping each metric card independently without blocking the page.
5. Document Management Table with Bulk Actions
 * Stack: HTMX + Alpine.js.
 * The Division:
   * Alpine.js: Drives the "Select All" checkbox state, toggles individual row highlight checkboxes, and controls an action toolbar that appears only when at least one row is checked.
   * HTMX: Triggers batch mutations. When the user selects "Bulk Archive" or "Bulk Delete", HTMX submits the serialized selection IDs, removes the deleted row fragments from the table via hx-swap="delete", and updates the total document count snippet.
Key Rules for Success
 * Avoid using Alpine for data synchronization. If an operation needs to query a database or persist data, use HTMX to talk to the server and return updated HTML.
 * Avoid using HTMX for momentary visual state. Opening a dropdown, showing an accordion item, or dismissing an alert should not incur an HTTP request. Let Alpine mutate local variables and toggle classes.
 * Embrace the HTML-over-the-wire model. Treat HTML partials as your API. You eliminate the cost of maintaining separate serialization layers, reducing your codebase down to pure hypermedia and fast user experiences.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>htmx</category>
      <category>aloinejs</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>15 Practical HTMX Project Ideas to Master Hypermedia published</title>
      <dc:creator>Digital Ghost</dc:creator>
      <pubDate>Fri, 25 Sep 2026 01:56:33 +0000</pubDate>
      <link>https://dev.to/digitalgh0st/15-practical-htmx-project-ideas-to-master-hypermediapublished-27ia</link>
      <guid>https://dev.to/digitalgh0st/15-practical-htmx-project-ideas-to-master-hypermediapublished-27ia</guid>
      <description>&lt;p&gt;—&lt;br&gt;
Ditch client-side bloat. Here are 15 real-world HTMX project ideas ranging from beginner patterns to production-level interactive systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  tags: htmx, webdev, javascript, programming
&lt;/h2&gt;

&lt;p&gt;Single Page Applications often introduce massive build pipelines, complex state hydration, and multi-tier store management for simple interactive features. HTMX returns power to standard HTML by letting you access AJAX, CSS Transitions, WebSockets, and Server-Sent Events directly through attributes.&lt;/p&gt;

&lt;p&gt;If you are looking to learn hypermedia concepts or build lightweight full-stack applications, here is a curated roadmap of 15 project ideas designed to take you from core mechanics to advanced architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Live Search with Active Debounce
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Incremental data retrieval based on keyboard input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-get&lt;/code&gt;, &lt;code&gt;hx-trigger="keyup changed delay:300ms, search"&lt;/code&gt;, &lt;code&gt;hx-target&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Replace bloated client-side search indexing. Users type into an input box, and the server returns rendered list items or table rows. The 300ms debounce ensures you do not flood your server with requests on every keystroke.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Multi-Step Registration Wizard
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: State preservation across multi-view forms without full page refreshes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-post&lt;/code&gt;, &lt;code&gt;hx-swap="outerHTML"&lt;/code&gt;, &lt;code&gt;hx-target&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Build an onboarding flow where each step submits data to the server, validates input, and returns the next form step directly into the DOM. Session state or temporary database tokens keep track of progress on the server.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Inline Table Editor (Click-to-Edit)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Dynamic view-to-form state swaps on specific table cells or rows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-put&lt;/code&gt;, &lt;code&gt;hx-target="this"&lt;/code&gt;, &lt;code&gt;hx-swap="outerHTML"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Display tabular data where clicking any row or cell replaces that row with an editable form fragment containing "Save" and "Cancel" buttons. Submitting changes persists data to the database and swaps back to standard text.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Real-Time Notification Feed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Push updates without client polling via Server-Sent Events (SSE).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-ext="sse"&lt;/code&gt;, &lt;code&gt;sse-connect&lt;/code&gt;, &lt;code&gt;sse-swap&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Connect a client page to an SSE streaming endpoint on your server. As background tasks complete, the server streams small HTML toast or list items that automatically prepend to the user's notification tray.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Instant File &amp;amp; Image Uploader
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Multipart form handling, progress tracking, and instant preview rendering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-post&lt;/code&gt;, &lt;code&gt;hx-encoding="multipart/form-data"&lt;/code&gt;, &lt;code&gt;hx-target&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Allow users to drag and drop or select files. The server handles validation, saves the image, and responds immediately with the rendered thumbnail markup to append to an existing gallery grid.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. Dynamic Dashboard Widgets
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Independent component loading and polling intervals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-get&lt;/code&gt;, &lt;code&gt;hx-trigger="load, every 30s"&lt;/code&gt;, &lt;code&gt;hx-swap="innerHTML"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Construct a metrics dashboard where each card or widget requests its own data independently upon page load. Slow queries in one card do not block the rest of the interface from rendering.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Server-Driven Modal Dialogs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Lazy-loading modals to keep initial page weights tiny.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-get&lt;/code&gt;, &lt;code&gt;hx-target="#modal-container"&lt;/code&gt;, &lt;code&gt;hx-swap="innerHTML"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Keep the root DOM clean by loading modal markup over the wire only when a button is clicked. Include an auto-cleanup pattern or native &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; toggle upon server response.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Infinite Scroll List
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Viewport-triggered pagination without client calculation of scroll offsets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-get&lt;/code&gt;, &lt;code&gt;hx-trigger="revealed"&lt;/code&gt;, &lt;code&gt;hx-swap="afterend"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Render a feed of items where the very last element contains &lt;code&gt;hx-trigger="revealed"&lt;/code&gt;. When the user scrolls down and the element enters the viewport, HTMX issues a request for page N+1, appends the new items, and attaches the trigger to the new last item.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. Background Job Progress Tracker
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Short-polling for long-running backend operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-get&lt;/code&gt;, &lt;code&gt;hx-trigger="every 1s"&lt;/code&gt;, &lt;code&gt;hx-target="this"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Trigger a heavy asynchronous task (such as report generation or video export) via a POST request. The server returns a progress bar that polls status every second until completion, at which point the server returns the final success state and stops polling.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Drag-and-Drop Sortable Kanban Board
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Integrating minimal third-party JavaScript libraries with HTMX events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-post&lt;/code&gt;, &lt;code&gt;hx-trigger="end"&lt;/code&gt;, Sortable.js integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Combine Sortable.js with HTMX. When a user drags a card from "In Progress" to "Done", a JavaScript event triggers an HTMX POST containing the reordered IDs directly to the backend to persist order and status.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  11. Paginated Server-Side Data Table
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Granular tabular replacement without resetting scroll positions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-get&lt;/code&gt;, &lt;code&gt;hx-target="#table-body"&lt;/code&gt;, &lt;code&gt;hx-push-url="true"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Build an administrative data table featuring sorting arrows, filter dropdowns, and page controls. Using &lt;code&gt;hx-push-url="true"&lt;/code&gt; keeps browser history and shareable URLs in sync without running full client-side router configurations.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  12. Cascading Dropdown Selectors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Interdependent form fields driven by parent choices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-get&lt;/code&gt;, &lt;code&gt;hx-target="#sub-category"&lt;/code&gt;, &lt;code&gt;hx-trigger="change"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Create dependent form controls (such as Country to State to City). When a user changes the primary dropdown, HTMX sends the selection to the backend, which returns the populated &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt; tags for the child selector.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  13. Active Tab Navigation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Lightweight tab switching with URL updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-get&lt;/code&gt;, &lt;code&gt;hx-target="#tab-content"&lt;/code&gt;, &lt;code&gt;hx-swap="innerHTML"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Instead of embedding heavy tabbed content into one massive initial payload or building client tabs with custom CSS classes and state, each tab requests its HTML partial from the server on demand.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  14. Optimistic UI with Undo Actions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Immediate client feedback paired with server synchronization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-delete&lt;/code&gt;, &lt;code&gt;hx-target="closest tr"&lt;/code&gt;, &lt;code&gt;hx-swap="outerHTML"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Build a task management interface where clicking "Delete" hides or crosses out an item immediately and shows a toast with an "Undo" trigger. If the undo window expires, the server permanently deletes the record.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  15. Real-Time Collaborative Canvas / Board
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Concept&lt;/strong&gt;: Bi-directional event communication using WebSockets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Attributes&lt;/strong&gt;: &lt;code&gt;hx-ext="ws"&lt;/code&gt;, &lt;code&gt;ws-connect&lt;/code&gt;, &lt;code&gt;ws-send&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt;: Build a simple multi-user canvas, status room, or voting board. Using the HTMX WebSocket extension, DOM elements listen for JSON/HTML broadcast streams sent across a socket connection, updating connected browsers without a full page refresh.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Build with HTMX?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero Client State Synchronization&lt;/strong&gt;: State lives on the server and in the DOM. No split brain between local caches and database reality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend Freedom&lt;/strong&gt;: HTMX works equally well with Go, Python, Rust, Node.js, PHP, or Java. Pick your favorite backend language.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller Footprints&lt;/strong&gt;: Deliver web pages that load in milliseconds on mobile devices without parsing megabytes of JavaScript frameworks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability&lt;/strong&gt;: Clear, readable HTML attributes make it obvious how and where dynamic behavior occurs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pick one idea, spin up a lightweight server, and build your next tool using hypermedia.&lt;/p&gt;

</description>
      <category>htmx</category>
      <category>javascript</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Vibe Coding with HTMX: Why Hypermedia is the Ultimate AI Pair-Programming Hack published</title>
      <dc:creator>Digital Ghost</dc:creator>
      <pubDate>Fri, 25 Sep 2026 01:24:40 +0000</pubDate>
      <link>https://dev.to/digitalgh0st/vibe-coding-with-htmx-why-hypermedia-is-the-ultimate-ai-pair-programming-hackpublished-2df4</link>
      <guid>https://dev.to/digitalgh0st/vibe-coding-with-htmx-why-hypermedia-is-the-ultimate-ai-pair-programming-hackpublished-2df4</guid>
      <description>&lt;p&gt;"Vibe coding"—prompting an LLM, accepting diffs, testing the feature, and shipping without obsessing over every boilerplate line—feels like magic until your frontend stack collapses under its own weight.&lt;/p&gt;

&lt;p&gt;If you’ve tried vibe coding with modern single-page application (SPA) architectures (React, Next.js, state machines, hydration lifecycles, and three layers of client-side cache), you know the breaking point:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;State synchronization hell:&lt;/strong&gt; The AI invents a &lt;code&gt;useEffect&lt;/code&gt; loop that triggers 40 rerenders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context bloat:&lt;/strong&gt; Feeding schemas, types, actions, components, and Tailwind tokens consumes half your model's context window before you even ask for business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ghost bugs:&lt;/strong&gt; The LLM misses an edge case where a client cache isn't invalidated after a server mutation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enter &lt;strong&gt;HTMX&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you shift from client-state SPAs to hypermedia-driven interfaces, LLMs go from erratic code spitters to hyper-competent engineering partners. Here is why HTMX is the best-kept secret for vibe coding, along with a production-ready blueprint to try it yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Problem: Why LLMs Struggle with Modern Frontend SPAs
&lt;/h2&gt;

&lt;p&gt;To understand why HTMX shines with AI, look at what an LLM must track when building a typical React or Vue feature:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend route &amp;amp; input validation schemas.&lt;/li&gt;
&lt;li&gt;ORM/database queries.&lt;/li&gt;
&lt;li&gt;API serialization &amp;amp; JSON response contracts.&lt;/li&gt;
&lt;li&gt;Frontend data fetching (React Query, RTK Query, Axios).&lt;/li&gt;
&lt;li&gt;Client state / store management (Zustand, Redux, Context).&lt;/li&gt;
&lt;li&gt;Rendering markup, DOM event listeners, and hydration boundaries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[Database] ↔ [Server Logic] ↔ [JSON API] ↔ [State Store] ↔ [Virtual DOM] ↔ [Real DOM]&lt;/p&gt;

&lt;p&gt;Every boundary is an opportunity for hallucination. If the backend changes a field from &lt;code&gt;snake_case&lt;/code&gt; to &lt;code&gt;camelCase&lt;/code&gt;, your AI assistant frequently fails to update the frontend state transformer three files away.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Hypermedia Collapse
&lt;/h3&gt;

&lt;p&gt;HTMX collapses that entire pipeline:&lt;/p&gt;

&lt;p&gt;[Database] ↔ [Server Logic + HTML Template] ↔ [Real DOM via HTMX]&lt;/p&gt;

&lt;p&gt;The server returns plain HTML chunks. HTMX swaps them directly into the DOM. There is no JSON serialization layer, no client-side store, and no synchronization logic. The state lives where it belongs: &lt;strong&gt;on the server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because LLMs are trained on decades of server-side templates (Django, Rails, Laravel, Go templates, Express/EJS), they write server-rendered HTML with near-perfect accuracy on the first shot.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Advantages of HTMX for Vibe Coding
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Minimal Cognitive &amp;amp; Token Overhead
&lt;/h3&gt;

&lt;p&gt;When you prompt an AI to create a feature with HTMX, you don’t need to paste 8 files. You paste one template or one server endpoint. The LLM can hold your entire route logic and its visual representation in a single prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Zero State Desync
&lt;/h3&gt;

&lt;p&gt;Because there is no separate client-side cache, bugs like "I clicked delete, but the item still appears until I refresh" simply don't happen. The server deletes the row and returns an empty string or the updated table markup. Done.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Framework Agnostic
&lt;/h3&gt;

&lt;p&gt;Whether you vibe code in Python (FastAPI/Flask), Go (Echo/Chi), Node.js (Express/Hono), or Rust (Axum), your HTMX syntax remains identical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hx-get&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hx-post&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hx-target&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hx-swap&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Hands-On Example: The Live Search &amp;amp; Quick Edit Pattern
&lt;/h2&gt;

&lt;p&gt;Let’s build an interactive search-and-edit interface. We'll use Node.js + Express with inline HTML template literals to keep everything in one compact file.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Main Shell (&lt;code&gt;server.js&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Here is how simple your application entry point is. Notice how HTMX attributes handle all the client-side behaviors that usually require hundreds of lines of React state.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
javascript
const express = require('express');
const app = express();

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

// In-memory mock store
let items = [
  { id: 1, name: "Dark Mode UI Kit", status: "Active" },
  { id: 2, name: "Analytics Dashboard", status: "Pending" },
  { id: 3, name: "Webhook Dispatcher", status: "Archived" }
];

// Base layout
app.get('/', (req, res) =&amp;gt; {
  res.send(`
    &amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html lang="en"&amp;gt;
    &amp;lt;head&amp;gt;
      &amp;lt;meta charset="UTF-8"&amp;gt;
      &amp;lt;title&amp;gt;HTMX + Vibe Coding Dashboard&amp;lt;/title&amp;gt;
      &amp;lt;script src="[https://unpkg.com/htmx.org@2.0.0](https://unpkg.com/htmx.org@2.0.0)"&amp;gt;&amp;lt;/script&amp;gt;
      &amp;lt;script src="[https://cdn.tailwindcss.com](https://cdn.tailwindcss.com)"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body class="bg-neutral-950 text-neutral-100 p-8 font-sans"&amp;gt;
      &amp;lt;div class="max-w-2xl mx-auto space-y-6"&amp;gt;
        &amp;lt;h1 class="text-2xl font-bold tracking-tight"&amp;gt;Project Overview&amp;lt;/h1&amp;gt;

        &amp;lt;!-- Live Search Input --&amp;gt;
        &amp;lt;div&amp;gt;
          &amp;lt;input 
            type="text" 
            name="q" 
            placeholder="Type to filter..." 
            hx-get="/search" 
            hx-trigger="keyup changed delay:300ms, search" 
            hx-target="#items-list" 
            class="w-full bg-neutral-900 border border-neutral-800 rounded px-4 py-2 focus:outline-none focus:border-neutral-500"
          /&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;!-- Dynamic Content Swap Target --&amp;gt;
        &amp;lt;div id="items-list" class="space-y-2"&amp;gt;
          ${renderList(items)}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  `);
});

function renderList(list) {
  if (list.length === 0) {
    return `&amp;lt;p class="text-neutral-500 text-sm"&amp;gt;No items found.&amp;lt;/p&amp;gt;`;
  }
  return list.map(item =&amp;gt; `
    &amp;lt;div id="item-${item.id}" class="flex items-center justify-between p-4 bg-neutral-900 border border-neutral-800 rounded"&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;div class="font-medium"&amp;gt;${item.name}&amp;lt;/div&amp;gt;
        &amp;lt;div class="text-xs text-neutral-400"&amp;gt;Status: ${item.status}&amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;button 
        hx-get="/items/${item.id}/edit" 
        hx-target="#item-${item.id}" 
        hx-swap="outerHTML"
        class="text-xs bg-neutral-800 hover:bg-neutral-700 px-3 py-1.5 rounded transition"&amp;gt;
        Edit
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  `).join('');
}

2. Interactive Endpoints (Search &amp;amp; In-Place Editing)
Now ask your LLM to add live filtering and in-place row editing. Instead of coordinating mutations and optimistic updates, the server simply returns small pieces of HTML:
// Live search query endpoint
app.get('/search', (req, res) =&amp;gt; {
  const query = (req.query.q || '').toLowerCase();
  const filtered = items.filter(item =&amp;gt; item.name.toLowerCase().includes(query));
  res.send(renderList(filtered));
});

// Returns the inline edit form
app.get('/items/:id/edit', (req, res) =&amp;gt; {
  const item = items.find(i =&amp;gt; i.id === parseInt(req.params.id));
  if (!item) return res.sendStatus(404);

  res.send(`
    &amp;lt;form 
      id="item-${item.id}" 
      hx-put="/items/${item.id}" 
      hx-target="#item-${item.id}" 
      hx-swap="outerHTML" 
      class="flex items-center gap-3 p-4 bg-neutral-900 border border-neutral-700 rounded"&amp;gt;

      &amp;lt;input 
        type="text" 
        name="name" 
        value="${item.name}" 
        class="bg-neutral-950 border border-neutral-800 px-3 py-1 text-sm rounded flex-1 focus:outline-none"
      /&amp;gt;

      &amp;lt;select name="status" class="bg-neutral-950 border border-neutral-800 px-2 py-1 text-sm rounded"&amp;gt;
        &amp;lt;option value="Active" ${item.status === 'Active' ? 'selected' : ''}&amp;gt;Active&amp;lt;/option&amp;gt;
        &amp;lt;option value="Pending" ${item.status === 'Pending' ? 'selected' : ''}&amp;gt;Pending&amp;lt;/option&amp;gt;
        &amp;lt;option value="Archived" ${item.status === 'Archived' ? 'selected' : ''}&amp;gt;Archived&amp;lt;/option&amp;gt;
      &amp;lt;/select&amp;gt;

      &amp;lt;button type="submit" class="text-xs bg-emerald-600 hover:bg-emerald-500 px-3 py-1.5 rounded font-medium"&amp;gt;Save&amp;lt;/button&amp;gt;
      &amp;lt;button 
        type="button" 
        hx-get="/items/${item.id}" 
        hx-target="#item-${item.id}" 
        hx-swap="outerHTML"
        class="text-xs bg-neutral-800 hover:bg-neutral-700 px-3 py-1.5 rounded"&amp;gt;
        Cancel
      &amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  `);
});

// Saves the update and swaps the row back to display mode
app.put('/items/:id', (req, res) =&amp;gt; {
  const item = items.find(i =&amp;gt; i.id === parseInt(req.params.id));
  if (!item) return res.sendStatus(404);

  item.name = req.body.name || item.name;
  item.status = req.body.status || item.status;

  res.send(`
    &amp;lt;div id="item-${item.id}" class="flex items-center justify-between p-4 bg-neutral-900 border border-neutral-800 rounded"&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;div class="font-medium"&amp;gt;${item.name}&amp;lt;/div&amp;gt;
        &amp;lt;div class="text-xs text-neutral-400"&amp;gt;Status: ${item.status}&amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;button 
        hx-get="/items/${item.id}/edit" 
        hx-target="#item-${item.id}" 
        hx-swap="outerHTML" 
        class="text-xs bg-neutral-800 hover:bg-neutral-700 px-3 py-1.5 rounded transition"&amp;gt;
        Edit
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  `);
});

// Read single row (used by "Cancel")
app.get('/items/:id', (req, res) =&amp;gt; {
  const item = items.find(i =&amp;gt; i.id === parseInt(req.params.id));
  if (!item) return res.sendStatus(404);
  res.send(`
    &amp;lt;div id="item-${item.id}" class="flex items-center justify-between p-4 bg-neutral-900 border border-neutral-800 rounded"&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;div class="font-medium"&amp;gt;${item.name}&amp;lt;/div&amp;gt;
        &amp;lt;div class="text-xs text-neutral-400"&amp;gt;Status: ${item.status}&amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;button 
        hx-get="/items/${item.id}/edit" 
        hx-target="#item-${item.id}" 
        hx-swap="outerHTML" 
        class="text-xs bg-neutral-800 hover:bg-neutral-700 px-3 py-1.5 rounded transition"&amp;gt;
        Edit
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  `);
});

app.listen(3000, () =&amp;gt; console.log('Listening on http://localhost:3000'));

Best Practices for Prompting AI with HTMX
When prompting your AI agent (Cursor, Claude, ChatGPT, Windsurf, Copilot), use these rules to keep outputs razor-sharp:
1. Give it the "Hypermedia Rules" System Prompt
Place this in your .cursorrules, system prompt, or conversation start:
We build using Server-Side Rendered HTML and HTMX.
Do NOT create JSON APIs or client-side stores unless explicitly requested.
Every endpoint returning interactive data should return an HTML snippet.
Always use proper hx-target, hx-swap, and hx-indicator attributes.
Prefer outerHTML swaps for modifying existing components in-place.

2. Prompt for Endpoints and Snippets Together
Instead of asking:
&amp;gt; "Create a REST API for deleting an order and write a React hook to mutate it."
&amp;gt; 
Prompt like this:
&amp;gt; "Write a DELETE /orders/:id endpoint that deletes the record from the DB and returns an HTTP 200 with an empty body, using hx-swap="delete" on the client button to remove the row from the DOM."
&amp;gt; 
The AI will output 8 lines of code instead of 60.
When HTMX Is the Right Vibe (and When It's Not)
| Ideal for HTMX + AI | Better with Traditional SPAs |
|---|---|
| CRUD apps, admin portals, dashboards | Offline-first mobile-style apps |
| Content platforms, internal tooling | Canvas/WebGL heavy apps (Figma, games) |
| Prototypes &amp;amp; fast MVP launches | High-density drag-and-drop spreadsheets |
| Single-developer or small-team builds | Multi-team decoupled API ecosystems |
The Takeaway
Vibe coding is all about tight feedback loops.
The more indirection your stack requires—build steps, compile errors, bundler hiccups, and hydration mismatches—the more your flow state breaks.
HTMX gives your AI assistant direct access to the DOM through the simplest protocol on earth: standard HTTP and HTML. The next time you fire up your AI code editor to build a tool, skip the heavy frontend bundle. Pair your model with HTMX and watch your ideas turn into functional software at lightspeed.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>htmx</category>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>I built a free carbon &amp; page-weight auditor for the web — feedback welcome</title>
      <dc:creator>Digital Ghost</dc:creator>
      <pubDate>Sun, 20 Sep 2026 03:44:02 +0000</pubDate>
      <link>https://dev.to/digitalgh0st/i-built-a-free-carbon-page-weight-auditor-for-the-web-feedback-welcome-5d4</link>
      <guid>https://dev.to/digitalgh0st/i-built-a-free-carbon-page-weight-auditor-for-the-web-feedback-welcome-5d4</guid>
      <description>&lt;p&gt;Hey DEV community 👋&lt;/p&gt;

&lt;p&gt;I've been working on a side project and I'd love some honest feedback before I push it further.&lt;/p&gt;

&lt;p&gt;It's called &lt;strong&gt;Tardigrade&lt;/strong&gt; — a free, browser-based auditor that tells you the carbon footprint and page weight of any URL. Paste a link, get an A–F grade in seconds. No signup, no tracking, no upsell.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://tardigrade-six.vercel.app/" rel="noopener noreferrer"&gt;tardigrade-six.vercel.app&lt;/a&gt;&lt;/p&gt;





&lt;h2&gt;Why I built it&lt;/h2&gt;

&lt;p&gt;The average web page now weighs over 2 MB. Some hit 10 MB. Most developers never see that number because nobody puts it in front of them.&lt;/p&gt;

&lt;p&gt;Every byte transferred costs electricity — servers, networks, devices. Using the &lt;strong&gt;Sustainable Web Design&lt;/strong&gt; model, we can estimate the carbon cost of a single page visit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;grams of CO₂ per visit = bytes transferred × 1.8 Wh/GB × 442 gCO₂/kWh
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's roughly 0.36 grams of CO₂ per megabyte. Sounds tiny — until you realize a bloated 5 MB page served to 10,000 visitors a day adds up fast.&lt;/p&gt;

&lt;p&gt;I wanted a tool that puts that number in front of developers without any friction.&lt;/p&gt;





&lt;h2&gt;What it does&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
&lt;strong&gt;Fetch&lt;/strong&gt; — Pulls live performance data from Google PageSpeed Insights (page weight, HTTP requests, load time, Lighthouse score).&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Calculate&lt;/strong&gt; — Runs the Sustainable Web Design formula to estimate CO₂ per visit.&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Grade&lt;/strong&gt; — Blends weight, CO₂, requests, load time, and Lighthouse into a single A–F score, plus color-coded metrics and concrete suggestions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nothing is stored. No accounts, no analytics on your audits, no email capture. Paste, read, leave.&lt;/p&gt;





&lt;h2&gt;Tech stack &amp;amp; design choices&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
&lt;strong&gt;Vanilla HTML/CSS/JS&lt;/strong&gt; — no framework bloat (would be ironic otherwise)&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Three.js&lt;/strong&gt; — animated hero with an abstract floating tardigrade made of wireframe geometry, orbited by red/yellow particles&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Vercel serverless function&lt;/strong&gt; — proxies PageSpeed Insights to avoid CORS and keep any API key hidden&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Scroll-triggered reveals&lt;/strong&gt; via IntersectionObserver&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Dark / light mode&lt;/strong&gt; respecting system preference&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Shareable URLs&lt;/strong&gt; — every audit gets a &lt;code&gt;?url=&lt;/code&gt; permalink for Slack/Discord sharing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The name comes from the tardigrade — the toughest animal on Earth. Survives radiation, vacuum, boiling, freezing. Your website should be just as resilient, and just as light.&lt;/p&gt;





&lt;h2&gt;What I'd love feedback on&lt;/h2&gt;

&lt;p&gt;This is where you come in. A few specific things I'm unsure about:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
&lt;strong&gt;Scoring weights&lt;/strong&gt; — Right now the grade blends page weight (30%), CO₂ (30%), requests (15%), load time (10%), and Lighthouse (15%). Are these the right ratios? Should load time matter more?&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;The carbon math&lt;/strong&gt; — I'm using the Sustainable Web Design model (1.8 Wh/GB × 442 gCO₂/kWh). Are there better or more current models I should support?&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;The UI&lt;/strong&gt; — Does the Three.js hero feel appropriate for a dev tool, or is it distracting?&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Missing metrics&lt;/strong&gt; — Anything you'd want to see that isn't there? (I'm considering adding TTFB, CLS, and per-resource-type breakdowns.)&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Mobile experience&lt;/strong&gt; — Does the input form and score card feel right on small screens?&lt;/li&gt;
&lt;/ul&gt;





&lt;h2&gt;Try it and tell me your grade&lt;/h2&gt;

&lt;p&gt;Honestly — paste your own site in and see what you get. Most people land on a C or D the first time. If you're brave, drop the grade in the comments 👇&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://tardigrade-six.vercel.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;tardigrade-six.vercel.app&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h2&gt;Roadmap (depending on feedback)&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Per-resource-type breakdown (images vs JS vs fonts)&lt;/li&gt;
  &lt;li&gt;"Greenest sites" leaderboard&lt;/li&gt;
  &lt;li&gt;Compare two URLs side-by-side&lt;/li&gt;
  &lt;li&gt;Downloadable audit report as PDF/image&lt;/li&gt;
  &lt;li&gt;Browser extension&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of these sound useful, let me know which one to prioritize.&lt;/p&gt;





&lt;p&gt;Thanks for reading. It's a solo project, so every bit of feedback helps. 🙏&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built by &lt;a href="https://www.digitalghost.blog" rel="noopener noreferrer"&gt;Digital Ghost 👻&lt;/a&gt; — free forever.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tough on weight. Kind to Earth.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>javascript</category>
      <category>auditor</category>
    </item>
  </channel>
</rss>
