← Back to Blog

realworld.io with NestJS + HTMX

March 14, 2025
NestJSHTMXTypeScriptNode.jsTypeORMHandlebarsRealWorld

Another HTMX and realworld.io project. Previously I have built Laravel + HTMX and Go Fiber + HTMX. This time I am using NestJS with TypeScript and Handlebars templates.

I already had experience with NestJS from building the fourth version of Fa'Diel. Pairing it with HTMX and the RealWorld spec felt like a natural next step to combine structured backend patterns with lightweight frontend interactivity.

The project: NestJS + HTMX and realworld.io

This was created to demonstrate a fully fledged fullstack application built with:

  1. NestJS - progressive Node.js framework with modules, decorators, dependency injection
  2. TypeORM - ORM with better-sqlite3 driver
  3. Handlebars (hbs) - server-side template engine
  4. HTMX - AJAX, CSS transitions, and partial swaps directly in HTML
  5. express-session - session-based authentication
  6. that adheres to the RealWorld specification

Dual rendering architecture

The app uses two layers of controllers working on the same URL paths:

  1. SSR controllers render full HTML pages on initial load via @Render() decorator
  2. HTMX controllers (under /htmx/*) return partial HTML fragments for subsequent SPA-like navigations

All links use hx-get + hx-target="#app-body" + hx-push-url, so clicking around feels like a single page application without a build step. The navbar and page title update via OOB (out-of-band) swaps in the same HTMX response.


HTMX integration highlights

  1. Favorite and follow buttons self-replace on click with hx-target="this" + hx-swap="outerHTML"
  2. Feed tabs switch content by targeting #feed-post-preview without reloading the page
  3. Form validation errors retarget to specific DOM elements using HX-Retarget + HX-Reswap headers
  4. Unauthenticated actions trigger HX-Redirect header to send users to the sign-in page
  5. Content feeds lazy-load on page load via hx-trigger="load"

Advantages:

  1. NestJS module system keeps the codebase organized even as it grows
  2. Handlebars partials enable reusable UI components without a frontend framework
  3. HTMX handles the SPA feel while the server stays in control of routing and state
  4. SQLite via better-sqlite3 means zero database setup, just clone and run
  5. Dual controller pattern clearly separates full-page renders from HTMX fragment responses

The repository and live example can be accessed below:

Repository
Live Example