How I Ship React Native Faster with Ignite, Rails/Elixir, and Hetzner

Today is unofficial React Native maintenance day, so I wrote down the stack that keeps me shipping features without burning a weekend. The short version: Infinite Red's Ignite template boots the mobile app in minutes, Rails or Elixir power the APIs, and Hetzner Cloud hosts everything without surprise bills.

The stack at a glance

  • Front end: Ignite with Expo 53, React Native New Architecture enabled, and the bundled generators.
  • Back end: Rails when I want batteries-included CRUD and Active Storage, Elixir/Phoenix when the feature needs soft-real-time channels or heavy concurrency.
  • Hosting: Hetzner Cloud CX/CPX instances, the same foundation I described in my Kamal + Hetzner guide.
  • Tooling: Ignite Cookbook recipes plus Bun for quick scripts, Solid Queue or Oban for background jobs, and Kamal for the Rails deploy path.

Ignite gives me week-one velocity

Ignite has shipped 270+ versions since 2016, so it's truly a real product not a weekend template. The latest release brings:

  • Expo-first workflow: Expo 53 plus Expo Router let me stay in TypeScript until I absolutely need native modules.
  • New Architecture on by default: I don’t have to toggle Fabric manually; Ignite’s config handles it.
  • Curated libraries: The boilerplate already includes high-quality navigation, theming, and testing tools vetted by the Infinite Red team.
  • Cookbook recipes: When I need a working example (push notifications, auth flows, file uploads), I grab a snippet from the Ignite Cookbook and trust it’s up to date.

Rails or Elixir depending on the flavor of the backend

Ignite’s data layer stays thin, so I lean on whichever backend matches the problem:

Rails for CRUD-heavy products
  • The JSON:API-compliant controllers live in the same repo as Active Admin dashboards.
  • SQLite or Postgres depending on the scale; Kamal deploys the API to Hetzner as I outlined in my 2026 Rails stack post.
  • Hotwire + Stimulus handle web clients, while the mobile app talks to versioned REST endpoints.
Elixir/Phoenix for real-time systems
  • Phoenix LiveView doubles as an admin console, but the React Native app uses Phoenix channels for streaming data.
  • Oban runs background workloads, and I expose GraphQL endpoints via Absinthe when the mobile app needs granular data fetching.

Both backends share a simple api.<project> convention, so Ignite’s .env stays consistent between projects.

Hetzner keeps costs chill without slowing down

Every service lands on Hetzner Cloud:

  • Backend VMs: CPX21 for Rails APIs, CPX31 for Elixir/Phoenix when I need more CPU headroom.
  • Databases: Managed Postgres or attached volumes for SQLite depending on the app.
  • Networking: Free firewalls, private networks, and IPv6 out of the box-perfect for Kamal deploys.
  • Monitoring: I let Kamal health checks guard the API, while Ignite’s Expo updates keep the client side fresh.

Once Kamal finishes a rollout, I trigger EAS Update or the App Store workflows knowing the backend is already warm.

My Ignite quickstart checklist

npx ignite-cli new studio-mobile \
  --expo \
  --bundle com.apb.studio

cd studio-mobile
bun install

# Generate the navigation + feature screens I need
npx ignite-cli g screen sessions/ListSessions
npx ignite-cli g model Session
  • The generators scaffold tests, storybooks, and hooks in one go.
  • I point .env to the domain.

Lessons learned (so far)

  1. Keep Ignite updated: Each point release of Ignite usually includes Expo and React Native patches, so I schedule a monthly dependency sweep.
  2. Don’t mix state managers prematurely: Ignite ships with sensible defaults; I add Zustand or MobX only when a feature needs it.

← Back to all posts