r/htmx

▲ 10 r/htmx

Chat Wells, a proximity chat room

Made this after getting and reading through a third of Hypermedia Systems, it's a simple chat room where you can post your status and see what others are posting in random spots across a board.

The more participation, the more true to form it will function. Give it a try if you have a sec.

stuff.kyleperik.com
u/qrdp — 1 day ago
▲ 169 r/htmx

My Experience Building a Social Website for My Startup with Go + HTMX 4 (Long Post)

https://preview.redd.it/kqel7842utjh1.jpg?width=2048&format=pjpg&auto=webp&s=b9cb2844e74e0c42bc80f89a5eba3eabd3a6a254

Conclusion first: HTMX is VERY production ready for a large-scaled project. And thankfully I ditched Vue.js 2/3 and Svelte 4 for HTMX. (Never used React though.)

I literally cried when HTMX mentioned they’re trying to be the next jQuery, that might not need to change for the next decade.

In the AI era, adding features becomes easy, but people just don’t know how to make things simple and “just work.” I really hope HTMX stays this way. (please u/_htmx 😭🙏)

The startup is basically an old Twitter clone, from when social media felt friendlier and the web didn’t feel like a bunch of boring mobile apps. Sorry for the mixed-language screenshots, I hadn’t finished internationalization yet.

 

Here are a few of my experiences with HTMX:

1. Make the website stupid and just make it work

We don’t use a cool dialog library like SweetAlert.js. The native alert(), confirm(), and prompt() just work. With hx-confirm, it’s even simpler.

If you need a form, just use <form>, and refresh the whole page if you can (or hx-post if you don’t want to), so you don’t have to worry about partial updates or syncing what changed.

 

2. We don’t use Alpine.js

It’s a very good solution if you want some hybrid JS, but it reintroduced the state management problem.

We had server-rendered JSON inside <script type="application/json"> so Alpine.js could load the data back. It worked, but caused some flickering since Alpine runs after the page is rendered, and introduced another state we had to manage.

so we decided to keep everything server-side rendered. (yea, fuck the network latency 🥳🎉)

We took this pretty far. When you upload photos in a post creation form, normally you’d just spawn the previews with JavaScript. Instead, we turn the images into blob URLs, pass those URLs to the server, and the server returns something like:

<div class="photo-preview">
    <img src="{{ .ImageURL }}">
</div>

So when the user edits the post later, we can render the exact same “photo preview” component on the server. One component, one rendering path.

>ℹ️ But there are also things you can just ditch.
>. 
>We had a post poll where you could use +/- buttons to add or remove option inputs with Alpine.js. Turns out we only support up to 4 options anyway, so we ditched the +/- JS and just put 4 fixed text inputs in the poll form.
>. 
>Now we can render the option text directly into the inputs, instead of outputting it as JSON in a <script> for Alpine.js to load back into them when user is editing the poll.

It sounds stupid. That’s kind of the point. You sacrifice some UX (user experience), but get much better DX (developer experience).

 

3. We don’t use Templ or framework with HTMX with Go

Since Templ requires build-tools, learning special syntax, IDE extensions, we decided to just use Go’s html/template and split the HTML into layouts, pages, and partials. The definitions look roughly like this:

type AppLayout struct {
    Navbar *Navbar
}

type ProfilePage struct {
    *AppLayout
    User         *User
    FollowButton *FollowButton
}

type FollowButton struct {
    IsFollowing bool
}

Then compose the data in the page handler:

user, err := db.GetUser(c.Param("username"))
if err != nil {
    return c.Abort(http.StatusInternalServerError)
}

layout := &AppLayout{
    Navbar: NewNavbar(),
}

// Tada- now you have a full page! 🎉
page := &ProfilePage{
    AppLayout:    layout,
    User:         NewUser(user),
    FollowButton: NewFollowButton(user.IsFollowing),
}

And if you want to render the Follow Button component:

{{ template "follow_button" .FollowButton }}

Since AI can write the boilerplate now, code can be stupid and boring, but easy to debug. And with HTMX, you can just return any partial when needed.

There’s no "runtime magic" to trace if error occurred, back when Vue.js + hot reload pointing stack traces to some generated chunks.js instead of the actual code.

u/yami_odymel — 3 days ago
▲ 56 r/htmx

Is PHP + HTMX + Alpine.js a serious alternative to Next.js for modern web apps in 2026?

The appeal for me is:

  • PHP remains the backend and renders HTML
  • HTMX handles partial page updates/AJAX
  • Alpine.js handles small client-side interactions
  • No React/Next.js application required
  • No npm install, bundler, Node server, etc.
  • Can deploy directly to normal PHP/shared hosting
reddit.com
u/webfuelcode — 4 days ago
▲ 71 r/htmx

Feeling nostalgic for the pre-AI era of learning new tech

I've been feeling nostalgic lately for the days before AI, back when building a simple TODO app was a genuine joy, a way to explore a new stack, and a way to relieve fatigue.

HTMX was one of those libraries for me.

Does anyone else miss that hands-on discovery phase?

reddit.com
u/packstub-dev — 8 days ago
▲ 14 r/htmx

Any luck with setting up HTMX auto-complete on neovim?

I really enjoy htmx, and using it without any type of lsp features is fine. however, it would still be better to have such.

I use neovim with the lazyvim distribution/setup, and the htmx lsp made by Primeagem (and available in mason) makes my html code completion stuff just not work anymore; other lsps seem to also just not work.

Anyone here got a working setup? i already posted about this in the neovim sub a while ago, but i figure it makes sense to post it here too.

edit: got an lsp working

reddit.com
u/Davi_Compai — 12 days ago