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.

Create a free account to save this page, take notes and track your progress. Sign in

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:

Your first htmx requestTry it yourself
<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 with id="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:

  1. Any element can send a request, not just links and forms.
  2. Any event can trigger it: a click, typing, scrolling into view, a timer.
  3. Any HTTP method can be used: GET, POST, PUT, PATCH, DELETE.
  4. 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.

This one sends a request as you type (waiting until you pause for 300 ms) and shows matching names:

Live search in four attributesTry it yourself
<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?

  1. An HTML fragment that htmx puts into the page
  2. JSON data that your JavaScript turns into HTML
  3. A whole new page that replaces the current one
  4. Nothing: 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.

Was this page helpful?