FastAPI and HTMX: A Modern Approach to Full Stack
Tags: fastapi, htmx, fullstack, python
Published: 2024-03-05 14:24:07

In my [last post](https://dev.to/jaydevm/a-quick-tour-of-htmx-3a6n) I talked about what HTMX is and the benefits of using it in your app. HTMX takes care of many frontend concerns, but what about backend? I love Python and FastAPI, and it happens that HTMX and FastAPI pair well together. The combination of these two technologies gives you a simple yet powerful end-to-end stack to build applications. Let’s see how they integrate!

## **The Benefits of FastAPI**

FastAPI is a modern, fast (high-performance) web framework for building APIs with Python 3.7+ based on standard Python type hints. Here are some of its key benefits:

- **Performance**: FastAPI is built on Starlette and Pydantic, making it as fast as NodeJS and Go (thanks to Starlette) and one of the fastest frameworks for Python.
- **Ease of Use**: It offers an intuitive API that makes it easy to use yet powerful. You can expect significant development speedup due to its simplicity.
- **Automatic Documentation**: With FastAPI, documentation for your API is generated automatically using Swagger UI and ReDoc, making it easier for developers to understand and use your API.
- **Type Safety**: Leveraging Python type hints, FastAPI helps catch errors early in development, leading to more robust and error-free code.

## **The Benefits of HTMX**

HTMX is a JavaScript library that allows you to access AJAX, CSS Transitions, WebSockets, and Server Sent Events directly in HTML, making it a powerful tool for enhancing web pages with dynamic content without writing complex JavaScript. Its benefits include:

- **Simplicity**: You can add dynamic behavior to your web pages using attributes directly in your HTML, making it easier to read and maintain.
- **Progressive Enhancement**: HTMX works as an enhancement on top of your existing server-rendered pages, allowing you to progressively enhance your web application's interactivity.
- **No Need for Complex JavaScript Frameworks**: With HTMX, you can create highly interactive web applications without relying on heavy JavaScript frameworks, leading to faster load times and improved performance.

## **Building a Full Stack App with FastAPI and HTMX**

Now that we understand the benefits, let's dive into creating a simple application that lists items and allows users to add new items to the list dynamically.

### **Step 1: Set Up Your Project**

First, create a new project directory and set up a virtual environment:

```bash
mkdir fastapi-htmx-demo
cd fastapi-htmx-demo
python3 -m venv venv
source venv/bin/activate
```

Install FastAPI, Uvicorn (an ASGI server), and Jinja2 for templating:

```bash
pip install fastapi uvicorn jinja2 python-multipart
```

### **Step 2: Create Your FastAPI Application**

Create a file named **`main.py`** and set up your FastAPI application and routes:

```python
from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory="templates")

# Dummy datastore
items = ["Item 1", "Item 2"]

@app.get("/", response_class=HTMLResponse)
def get_items(request: Request):
    return templates.TemplateResponse("items.html", {"request": request, "items": items})

@app.post("/add-item")
def add_item(request: Request, item: str = Form(...)):
    items.append(item)
    return templates.TemplateResponse("partials/item.html", {"request": request, "item": item})
```

### **Step 3: Set Up Jinja2 Templates**

Create a **`templates`** directory and add an **`items.html`** file:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FastAPI + HTMX Demo</title>
    <script src="https://unpkg.com/htmx.org"></script>
</head>
<body>
    <h1>Item List</h1>
    <ul id="item-list">
        {% for item in items %}
        <li>{{ item }}</li>
        {% endfor %}
    </ul>
    <form hx-post="/add-item" hx-target="#item-list" hx-swap="beforeend" hx-include="#item-input">
        <input type="text" id="item-input" name="item" required>
        <button type="submit">Add Item</button>
    </form>
</body>
</html>
```

Next, create a template partial called **`item.html`**. This will be used to render new items in the FastAPI server as they are added via HTMX POST call in the browser.

```html
<li>{{ item }}</li>
```

### **Step 4: Run Your Application**

Run your application using Uvicorn:

```bash
uvicorn main:app --reload
```

Visit **`http://127.0.0.1:8000`** in your browser to see your application in action.

If you’re interested in seeing all the code in one place, check it out here: https://github.com/jaydev/fastapi-htmx-demo

### **Conclusion**

FastAPI provides a robust backend, offering high performance and ease of development, while HTMX allows for dynamic frontend interactions with minimal effort. This tech stack has an easy learning curve and is useful in a wide variety of situations.

I know I’ll be reaching for this combination in the future as I build apps. Let me know what your favorite HTMX backend pairing is in the comments!