htmx Tutorial · htmx Basics · Lesson 1 of 30
htmx Introduction
What htmx is, the one idea behind it, how it differs from React-style apps, and a first live example.
What is htmx?
htmx is a small JavaScript library (about 16 KB compressed) that lets you build interactive web pages by writing
HTML attributes instead of JavaScript. You add attributes such as hx-get or hx-post to an element, and when
the user clicks it (or types, scrolls, submits...) htmx sends a request to your server and puts the HTML the server
returns into the page.
Here's the whole idea in one example. Press the button: htmx sends GET /hello to the server and puts the reply
inside the <div>. The grey box under the example is a log of the requests the page made:
<button hx-get="/hello" hx-target="#greeting">Say hello</button>
<div id="greeting"></div>
<!-- The pretend server: on a real site this part is your backend (Python, PHP, Node, Go...) -->
<script>
server.get("/hello", () => "<p>Hello! This HTML came from the server.</p>");
</script>
Read the button's attributes out loud and they explain themselves:
hx-get="/hello": when this element is triggered, send a GET request to/hello.hx-target="#greeting": put the response into the element withid="greeting".
No fetch(), no addEventListener, no JSON parsing, no code to build DOM elements. The server sends finished HTML,
and the browser does what it's best at: showing HTML.
The problem htmx solves
Plain HTML can only make requests in two ways: a link (<a>) and a form (<form>). And each of them replaces
the whole page. To update just part of a page, for example a "Like" counter, a search result list or one row of a
table, you traditionally needed JavaScript.
htmx removes those limits. With htmx:
- Any element can send a request, not just links and forms.
- Any event can trigger it: a click, typing, scrolling into view, a timer.
- Any HTTP method can be used:
GET,POST,PUT,PATCH,DELETE. - Any part of the page can be updated, not only the whole window.
How is it different from React or Vue?
| Single-page app (React, Vue, Angular) | htmx | |
|---|---|---|
| What the server sends | JSON data | HTML fragments |
| Who builds the HTML | JavaScript in the browser | Your server templates |
| Where state lives | Mostly in the browser | On the server |
| JavaScript you write | A lot (components, state, routing) | Little or none |
| Build step | Usually (Vite, webpack) | None: one <script> tag |
This style is called hypermedia-driven: the server answers with hypermedia (HTML), just like the original web, and htmx makes it more interactive. It suits server-rendered apps built with Django, Flask, FastAPI, Rails, Laravel, Express, Go or ASP.NET. Any language that can return HTML can be an htmx backend.
A second taste: live search
This one sends a request as you type (waiting until you pause for 300 ms) and shows matching names:
<input type="search" name="q" placeholder="Search a name..."
hx-get="/search" hx-trigger="input changed delay:300ms" hx-target="#results">
<ul id="results"></ul>
<!-- The pretend server: on a real site this part is your backend (Python, PHP, Node, Go...) -->
<script>
const people = ["Ada Lovelace", "Alan Turing", "Grace Hopper", "Linus Torvalds", "Margaret Hamilton"];
server.get("/search", (req) => {
const q = (req.query.q || "").toLowerCase();
return people.filter((p) => p.toLowerCase().includes(q))
.map((p) => `<li>${server.escape(p)}</li>`).join("");
});
</script>
In the next pages you'll learn every attribute used here. First, set up htmx.
Test yourself
What does an htmx server usually send back in response to a request?
An HTML fragment that htmx puts into the pageJSON data that your JavaScript turns into HTMLA whole new page that replaces the current oneNothing: htmx works only in the browser
Show answer
Answer: An HTML fragment that htmx puts into the page
htmx is hypermedia-driven: the server renders HTML and htmx swaps it into the target element.