Meet Oxpecker.Alpine and Oxpecker.Htmx beta
This post introduces new Oxpecker “built-in” wrappers for two relatively popular JavaScript frameworks.
Meet Oxpecker.Alpine and Oxpecker.Htmx beta

Oxpecker + Htmx + Alpine = ❤️
This post introduces new Oxpecker “built-in” wrappers for two relatively popular JavaScript frameworks.
Although **Alpine.js and [Htmx.js](https://htmx.org/) **are two separate libraries with independent authors, they are commonly used together and not without a reason:
- I’ve never had a real project where using *only *Htmx was possible and it’s difficult to come up with one, since client-only interactions are almost always required here and there.
- It’s hard to justify using *just *Alpine for JavaScript-based frontends, because it is just less powerful, performant and convenient compared to more popular alternatives (where Solid.js is still my top choice)
- But together they work just right with Htmx doing most of the heavy lifting and Alpine being used on demand, where interaction without any server communication is preferable. FWIW, Alpine is recommended by the authors of the main Htmx book.
Oxpecker.Htmx has been published for a while, but I always felt that Oxpecker.Alpine was missing. I did try to come up with the API similar to Htmx one few years ago, but didn’t succeed, so only returned back to this task after I heard about new Htmx version 4 coming.
Htmx4 bring lots of breaking changes, actually so many, that migrating a tiny project took me several days. I honestly don’t think there is a big reason to migrate an existing big project to v4, since v2 is going to be supported just as long as v4. The changes include removing or renaming attributes and headers, changing event names and object structures, changing extension rules, changing the request engine and many other things. It is a huge update of both API and internals.
However, when you are starting a greenfield project, jumping straight to v4 makes much bigger sense, so I decided that Oxpecker users shouldn’t miss out and started working on a wrapper for v4. At the same time I kept Alpine in mind, so both libraries could be accessed using similar API.
Htmx4 and Alpine attributes are not just some regular attributes, take a look at their format:
<!-- Htmx4 inheritance -->
<div hx-include:inherited="#global-fields">
<form hx-include:inherited:append=".extra">...</form>
</div>
<!-- Htmx4 modifiers and extended selectors -->
<div hx-swap="innerHTML scroll:top scrollTarget:#other">...</div>
<!-- Alpine.js events -->
<button x-on:click="message = 'changed'">...</button>
<!-- Alpine.js modifiers -->
<div @scroll.window.throttle.750ms="handleScroll">...</div>
After several attempts I figured out that keeping their attributes as setter properties is no longer feasible. The best solution I found was to rely on extension methods for special attributes, just like for event handlers. With Oxpecker.Htmx and Oxpecker.Alpine the HTML examples above now translate into the following:
// Htmx4 inheritance (option 1)
div().hxInclude("#global-fields", ":inherited") {
form().hxInclude(".extra", ":inherited:append")
}
// Htmx4 inheritance (option 2)
div().hxInclude("#global-fields", HxModifier.inherited) {
form().hxInclude(".extra", HxModifier.inherited + HxModifier.append)
}
// Htmx4 modifiers and extended selectors (option 1)
div().hxSwap("innerHTML scroll:top scrollTarget:#other")
// Htmx4 modifiers and extended selectors (option 2)
div().hxSwap(HxSwapMethod.innerHtml
+ HxSwapModifier.scroll "top"
+ HxSwapModifier.scrollTarget "#other")
// Alpine.js events
button().xOn("click", "message = 'changed'")
// Alpine.js modifiers (option 1)
div().xOn("scroll.window.throttle.750ms", "handleScroll")
// Alpine.js modifiers (option 2)
div().xOn("scroll"
+ XOnModifier.window
+ XOnModifier.throttleMs 750, "handleScroll")
I’ve decided to proceed with the string-based API, since it can be used both with module helpers (humans) and plain constant strings (LLMs). Performance-wise, constant strings are preferred, but I have big hopes that JIT-compiler will be able to optimize concatenation of constant strings in .NET 11.
I’ve used it in a small pet project and found the separation between standard HTML attributes (they are still properties) and extension method quite convenient. Modifier modules surprisingly serve as a good documentation of what is allowed by Alpine.
The packages have been published (Oxpecker.Htmx, Oxpecker.Alpine), documentation (Oxpecker.Htmx, Oxpecker.Alpine) and examples . One thing to note, the Htmx package is still in beta, so the corresponding Oxpecker package is in beta as well. Second thing to note — as Htmx jumped from v2 to v4, I decided to respect the author and bump Oxpecker.Htmx from v2 to v4 as well, hopefully this won’t be confusing to users.
As a side note, all Oxpecker packages now contain both xml documentation and source link information, which helps to navigate through Oxpecker APIs using IDE. And if you mainly use AI agents, you are also covered, since I’ve published a skill that allows agents to explore any public Nuget package API using reflection.
Thank you for reading and happy to hear any feedback about the published libraries!
메타데이터
- post_id
- 8b1dc7ebf89e
- slug
- meet-oxpecker-alpine-and-oxpecker-htmx-beta-8b1dc7ebf89e
- url
- https://medium.com/@lanayx/meet-oxpecker-alpine-and-oxpecker-htmx-beta-8b1dc7ebf89e
- canonical_url
- https://medium.com/@lanayx/meet-oxpecker-alpine-and-oxpecker-htmx-beta-8b1dc7ebf89e
- author_url
- https://medium.com/@lanayx
- status
- ok
- fetched_at
- 2026-07-09 22:34:41