Rails + Hotwire + SQLite (the no-React DHH stack) icon

Rails + Hotwire + SQLite (the no-React DHH stack)

Stack

The 2024-2026 DHH stack: Rails 8, Hotwire for HTML-over-the-wire interactivity, SQLite as the production database. No React, no SPA, server-rendered HTML, and that's a real SEO advantage.

Stack

What this is

The stack DHH spent 2024 evangelising and that 37signals shipped HEY and Basecamp’s newer apps on. No React. No JSON API. No SPA. Just server-rendered HTML, Hotwire for interactivity, SQLite for everything (data, jobs, cache, cable). The simplest way to ship a real product in 2026, and arguably the fastest in dev loop and runtime.

SEO advantage

Because every page is server-rendered HTML with content present on first paint, this stack has the best possible SEO posture. Google indexes the actual content, not a hydrated shell. No SSR/CSR juggling. No ‘render the route to an empty <div id="app"> and pray the bot waits for JavaScript’ fragility. A real win for marketing pages and content-heavy apps.

When to pick this stack

  • You want the smallest possible team-and-tooling footprint.
  • The product is mostly forms-and-pages with a sprinkle of real-time updates (the 95% of products that aren’t Figma or Linear).
  • SEO matters and you don’t want to fight a JS framework over it.

What we’d swap

  • SQLite → Postgres: only if you’ll eventually need cross-region replication, partitioning, or features SQLite genuinely lacks (full-text isn’t one of them, SQLite’s FTS5 is excellent).
  • Add React via Vite: only when a single page genuinely needs SPA UX. See Rails + React + Vite.

Common gotchas

  • SQLite likes a single writer. The Rails 8 SQLite adapter handles WAL mode and concurrent reads, but if you’re doing serious write throughput (>100/s sustained), benchmark first.
  • Backup strategy matters: litestream streaming the SQLite file to S3 is the canonical setup.

Tags

In this stack

7 tools
Ruby on Rails

The original opinionated full-stack framework: Active Record ORM, conventions, generators, and Hotwire for HTML-over-the-wire interactivity.

Used here for: Rails 8 with Active Record, Action Mailer, Solid Queue (jobs), Solid Cable (websockets), and Solid Cache, all backed by SQLite.

Hotwire (Turbo + Stimulus)

HTML-over-the-wire stack from 37signals: Turbo (server-rendered partial updates) plus Stimulus (sprinkles of JS). Skip the SPA, ship the monolith.

Used here for: Turbo + Stimulus. Server-rendered HTML with partial updates, broadcasts, and a tiny JS layer for genuinely client-side bits. The reason this stack feels SPA-fast without being one.

SQLite

Single-file embedded SQL database. Production-grade for surprisingly large workloads; the Rails 8 default and the canonical indie-hacker DB.

Used here for: Production database. Rails 8 defaults to SQLite for app data, jobs, cache, and cable, one file, no DB server. Easy backups (litestream), trivially fast, and zero ops.

GitHub

Industry-standard Git hosting with Copilot, Actions CI/CD, and the largest dev community. GitHub handles version control and team collaboration, branches, pull requests, code review, CI/CD, and project knowledge.

Used here for: Source control.

Fly.io

Deploy applications globally at the edge with native multi-region Postgres. Fly.io handles deployment and hosting, often with a global edge network and zero-config CI/CD.

Used here for: Deploy. Single VPS-style box with persistent volumes for the SQLite file. Hatchbox or Kamal works equally well.

Stripe

Developer-first payments with Billing, Connect, and Radar. Stripe handles online payments, checkout, subscriptions, billing, and compliance.

Used here for: Payments.

Sentry

Application error tracking and performance monitoring.

Used here for: Error monitoring.

Related