The htmx quick start pins 2.0.11 while the tags are at v4.0.0
GitHub describes it as htmx - high power tools for HTML. The repository metadata lists JavaScript as its primary language. The metadata lists the NOASSERTION license. This article stays within the project description and details documented in the GitHub repository README.
At a glance
- What is it?
- htmx gives HTML attributes access to AJAX, CSS transitions, WebSockets and server-sent events, shipping about 14k gzipped with no runtime dependencies. The page is small and confident, and the specific things a reader has to check are all in the metadata: the quick start installs version 2.0.11 from a CDN while the repository's newest tag is v4.0.0, two of the last three releases were 4.0.0 betas, and the manifest declares 0BSD where the repository metadata declares no licence at all.
- Who is it for?
- Adopt htmx when your server already returns HTML and you want interactivity without a build step, a client framework or a state layer, since the whole library is a script tag and the contract with your backend is an attribute plus a fragment. Do not adopt it expecting WebSockets or server-sent events in the box, because those two live on extension pages, and do not expect the README to discuss failure handling, which it does not.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The quick start snippet pins 2.0.11 and the tags say v4.0.0
Start with the version, because it is the first thing that will surprise you. The quick start loads a script from a CDN at a fixed version:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/htmx.min.js"
integrity="sha384-2OatzQy1H+Zd/IIrjr1TcuDGqLXeHhbooAyJY1KdQMKnr4LZ22k31GBLdYKHmVjg"
crossorigin="anonymous"></script>The manifest in the repository also says version 2.0.11. The release tags say something else: v4.0.0 on 2026-08-28, preceded by v4.0.0-beta6 on 2026-07-23 and v4.0.0-beta5 on 2026-06-26. So the page you are reading installs a two-major-version-old library, and the integrity hash is tied to that exact file, which means editing the version in the URL invalidates it. Two beta releases six weeks apart also describe a long stabilisation period for 4.0, and the last push to master is dated 2026-09-22.
There is an old broken package called htmx, and this one is htmx.org
The npm route is one command, and the page follows it with the most useful warning in the whole read:
npm install htmx.org --saveThe note under it says there is an old broken package called htmx, and that this one is htmx.org. That is a naming collision, and it is the failure mode most likely to cost you an afternoon: a package name that looks like an obvious abbreviation resolves to something nobody maintains, and the symptom is a missing or misbehaving library rather than an error at install time. The manifest confirms the name, htmx.org, with htmx as the description, high power tools for html. If you are evaluating htmx, check the name in your lockfile before you check anything else about it.
An attribute replaces the anchor, the form, and the click handler
The argument is a list of four questions, and they are the whole design. Why should only a and form be able to make HTTP requests? Why should only click and submit events trigger them? Why should only GET and POST be available? Why should you only be able to replace the entire screen? The example answers them in one element, a button that posts to a path and swaps itself:
<button hx-post="/clicked" hx-swap="outerHTML">
Click Me
</button>The page reads that back as: when a user clicks this button, issue an AJAX request to /clicked, and replace the entire button with the response. Note where the responsibility sits. Your server returns an HTML fragment, and the swap attribute decides what happens to the element that made the request, so the API shape and the DOM shape are designed together. The README says nothing about what a failed request looks like, so error rendering is a decision your templates have to make.
WebSockets and SSE are extension pages, not the core script
The opening sentence advertises four things: AJAX, CSS Transitions, WebSockets and Server Sent Events, all directly in HTML using attributes. Look at where two of them link. AJAX and CSS transitions point into the documentation, while WebSockets points at htmx.org/extensions/ws/ and Server Sent Events at htmx.org/extensions/sse/, which is the extensions index. So the script tag from the quick start gives you request-driven updates, and the two push-based protocols are separate extensions you add. The repository is arranged the same way, with an ext directory in the source tree and an extension test area under /test/ext. The consequence for an evaluation is simple: the headline sentence overstates what one file contains, and a project that genuinely needs a live feed is doing a second integration.
npm test runs lint, a type check, and Chromium, nothing else
The test entry point is a chain of three steps:
"test": "npm run lint && npm run types-check && npm run test:chrome",
"test:chrome": "playwright install chromium && web-test-runner --browsers chromium --playwright",Firefox and WebKit have their own targets, and test:all runs all three with concurrency set to one, so the cross-browser story is available but not the default. The type check is a real part of the gate rather than an afterthought, compiling the single source file with checkJs and skipLibCheck. The hacking guide describes a different loop for humans: install the development dependencies, run a web server in the root with npx serve, then open the test page at http://0.0.0.0:3000/test/, where mocha, chai and sinon mock out the AJAX requests. Tests live under /test by area, including /test/manual for cases that cannot be automated, which is a standing gap rather than a temporary one.
The npm tarball is build output, gzipped, plus editor metadata
Look at what the manifest ships and the delivery model becomes clear. The files array contains the licence, the readme, the type declarations, dist/*.js, dist/ext/*.js, dist/*.js.gz and a JetBrains web-types file, with main pointing at an ES module build and the jsdelivr and unpkg fields both pointing at the minified file. The dist script regenerates all of it from a shell script plus a declaration pass and a web-types pass, so what you install is generated output rather than source. Two consequences. Upgrading htmx means replacing a bundle, and the extensions under dist/ext travel in the same package. And the dependency-free claim is a runtime claim: the repository itself leans on mocha, chai, sinon, Playwright and a web test runner, none of which reach a consumer of the library.
The manifest says 0BSD and the repository declares no licence
Licence information is inconsistent in a way worth resolving before you build on it. The npm manifest carries license 0BSD, and a LICENSE file sits at the root of the tree next to SECURITY.md, CHANGELOG.md, TESTING.md and CONTRIBUTING.md. The repository metadata, meanwhile, records no licence. Both cannot be the answer a compliance process wants, so read the file rather than the badge. The maintenance picture is healthier. The last push to the default branch is dated 2026-09-22, and the release history shows v4.0.0 published on 2026-08-28 after two 4.0.0 betas in June and July, so the 4.0 line is out and the work is current. The project also describes itself as the successor to intercooler.js, which tells you where the design came from and whom to ask when a behaviour surprises you.
Editorial conclusion
Adopt htmx when your server already returns HTML and you want interactivity without a build step, a client framework or a state layer, since the whole library is a script tag and the contract with your backend is an attribute plus a fragment. Do not adopt it expecting WebSockets or server-sent events in the box, because those two live on extension pages, and do not expect the README to discuss failure handling, which it does not. Verify four things first. Check the version you are actually installing, because the quick start snippet pins [email protected] with a matching integrity hash while the newest tag is v4.0.0, so copying the snippet verbatim gives you a library two major versions behind. Install htmx.org and not htmx, since the page warns that an old broken package carries the shorter name. Read the LICENSE file rather than the repository metadata, because the npm manifest says 0BSD and the repository declares nothing. And if you are contributing, note that npm test covers lint, a type check and Chromium only, with separate targets for Firefox and WebKit.
Frequently asked questions
Is htmx faster than React?
The page makes no performance comparison with React or anything else, and offers no benchmark. Its only quantitative claim is size, about 14k min.gz'd, plus dependency-free and extendable. The argument it does make is architectural, about why only anchors and forms should be able to make HTTP requests.
What are the disadvantages of htmx?
The README states none. What the page does show is scope: WebSockets and Server Sent Events are linked as extensions rather than shipped in the core script, the swap target is chosen by an attribute such as hx-swap="outerHTML" so your server owns the returned fragment, and nothing is said about how a failed request should render.
What is the current version of htmx?
The two sources disagree. The newest release tags are v4.0.0 on 2026-08-28, preceded by v4.0.0-beta6 and v4.0.0-beta5, while the package manifest and the quick start snippet both say 2.0.11. The last push to the default branch is dated 2026-09-22.
Is htmx worth it?
That is your call, and the page gives you the facts it thinks matter: dependency-free, about 14k min.gz'd, extendable, and able to reach AJAX, CSS transitions, WebSockets and server-sent events from HTML attributes. It is also described as the successor to intercooler.js, and the project takes contributions through CONTRIBUTING.md and sponsorships.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bigskysoftware-htmx)