The Rails developers' guide to mobile app frameworks | Masilotti.com

8 min read Original article ↗

You have a Rails app. Your users want a mobile app. And now you’re staring down a handful of options, each with different tradeoffs.

This isn’t a “just make it responsive” situation. You want an actual app in the App Store and Google Play (or at least you’re considering it). So, which framework do you pick?

I’ve helped dozens of teams make this exact decision and shipped 25+ mobile apps backed by Rails. Here’s how I walk through the decision for each of my clients.

The four real options #

There are four paths worth seriously considering for a Rails team. Each one trades off development speed, native feel, and long-term maintenance differently.

Native (Swift and Kotlin) #

Building fully native apps means writing separate iOS and Android codebases in Swift and Kotlin, on top of your existing Rails app. You get full control over every pixel and every interaction. Fully native Swift and Kotlin apps feel incredible.

But you’re building everything three times. Every screen, every flow, and every feature needs an iOS version, an Android version, and the web version you already have. And if your Rails frontend is HTML-based (e.g. ERB, Hotwire, Turbo), you’ll also need to build a JSON API to power those native screens. That means new features can require work in four places: the data model, the API, the iOS UI, and the Android UI.

You will most likely need dedicated mobile developers (or need to become one) and you’re maintaining three codebases indefinitely. For most Rails teams, this is the most expensive option by a wide margin.

React Native #

React Native lets you write one JavaScript codebase that runs on both iOS and Android. It’s backed by Meta, has a massive ecosystem, and produces apps that feel close to native.

You never have to open Xcode or Android Studio with React Native. You write code in your editor of choice, run a command, and see the result in a device simulator. The developer ergonomics are quite good once you’re up and running. Though getting to that point can be its own adventure. Setting up React Native projects is notoriously finicky, not unlike the React ecosystem on the web.

React Native also has a large plugin ecosystem for adding native features like cameras, maps, and biometrics. But if you need something custom that doesn’t have a plugin, you’re writing native modules in Swift or Kotlin anyway. And now you’re fighting against the abstraction layer rather than working with the platform directly. It can end up being more work than just building the feature natively.

Here’s the catch for Rails teams: it’s still a completely separate codebase. You’re building a new frontend in React, creating an API layer to talk to your Rails backend, and duplicating logic. And despite the name, React web and React Native are different enough that you can’t share frontend code between them. You’re pretty much building the frontend twice.

PWA (Progressive Web App) #

A Progressive Web App skips the app stores entirely. Your Rails app runs in the browser, and users can “install” it to their home screen. It has zero native toolchain overhead and the lowest development cost.

The tradeoffs are real, though. No in-app purchases, limited push notification support on iOS, and no presence in the app stores. You lose discoverability and the legitimacy that comes with being downloadable. And honestly, it’s quite rare for anyone to actually click “Add to Home Screen.” Or even know where to find it.

That said, if you don’t need the app stores, a PWA lets you move fast with the fewest constraints.

Hotwire Native #

Hotwire Native wraps your existing Rails app in a native shell. Your HTML from the server gets rendered inside native navigation, so your Rails views are the mobile app. All of the business logic stays in one place: your Rails server. When you deploy a new feature or fix a bug, you change your Rails code and the apps update in real time. No app store review required.

When you need native features like push notifications, camera access, or biometrics, you add them with bridge components that connect your HTML to native code. And you can always “drop down to native” for fully custom screens when the situation calls for it.

I wrote an entire book on this approach. It’s also how 37signals builds Basecamp, HEY Email, and HEY Calendar, serving millions of paying customers across iOS and Android. These aren’t toy apps. They’re revenue-generating products built and maintained by a small team, because Hotwire Native lets them keep most of the work on the server.

The big tradeoff: you’re managing Xcode and Android Studio projects directly, and you’ll need to write a bit of Swift and Kotlin. But the amount of native code stays small because most of the work, and the core logic, stays on the server.

One thing to be aware of is that Hotwire Native doesn’t currently have offline support. Your app needs a network connection to load screens. This may be changing soon, but for now, if your users need to work without connectivity, this is a real limitation.

How they compare #

Here’s a side-by-side to make the tradeoffs concrete:

  Native React Native PWA Hotwire Native
Timeline 6-12+ months 4-8 months 1 week 1-2 months
Codebases 3 2 1 1 + 2 small1
Teams needed iOS, Android, and Rails React Native and Rails Rails Rails
Learning curve Steep Moderate None Low
Offline support Full Full Partial None
Native feel Full Full Minimal Mostly
App Store presence Yes Yes No Yes
Native API access Full Full Limited Full

1Hotwire Native technically has three codebases, but the iOS and Android projects are thin wrappers. Most of your development time stays in Rails.

The “teams needed” row is the biggest differentiator for most businesses: Hotwire Native and PWAs are the only options where your existing Rails developers can do the work.

When to pick each #

Pick fully native if… #

The mobile app is your product, not a companion to a web app. You need heavy offline support, you have or can hire dedicated iOS and Android developers, and budget and timeline aren’t major constraints. If all four of those are true, native will give you the best possible experience.

Pick React Native if… #

Your team is already using React on the web and you have an API layer built. The JavaScript knowledge transfers and you’re not starting from scratch. But if your frontend is server-rendered Rails (e.g. ERB, Hotwire, Turbo), adopting React Native means building an entirely new frontend skill set on top of the framework itself.

Pick a PWA if… #

You don’t need the app stores. Your app is primarily content or information display, push notifications on iOS aren’t important, and budget is tight. A PWA is the fastest path to “mobile app” when the stores aren’t a requirement.

Pick Hotwire Native if… #

You have a working Rails app with real users and you want to get into the app stores in weeks, not months. You don’t have mobile developers and don’t want to hire them. You want one codebase powering the majority of web, iOS, and Android. If that sounds like your situation, my book will walk you through building it yourself, or I can help you plan the right approach.

What about Flutter and Capacitor? #

Two other frameworks come up in these conversations. Here’s the short version.

Flutter is Google’s cross-platform framework using Dart. It has a custom rendering engine and produces pixel-perfect apps across platforms. But it requires learning a new language, building a completely separate codebase, and creating new APIs. There’s minimal code reuse with your Rails app. If your app is mobile-first and Rails is just the API, Flutter is worth considering. But for a Rails business adding mobile? It’s overkill.

Capacitor wraps a web app in a native shell with a plugin bridge for native APIs. It’s designed for JavaScript SPAs (React, Vue, Angular) bundled into the native binary and has good offline support since assets ship locally. But if you’re using server-rendered Rails, Capacitor creates a mismatch. You’d either build a redundant JS frontend or use their officially unsupported server mode. It’s a good tool for JavaScript teams, not a natural fit for Rails developers.

Still not sure which framework to choose? #

The right answer depends on your team, your timeline, and what your users actually need. There’s no universal “best framework,” just the one that fits your situation.

If you’d rather have someone help you figure out the right approach before writing any code, take a look at the Mobile Playbook. In two weeks you’ll have a framework recommendation, architecture diagram, risk register, and a phased build plan.

And if you just want to follow along as I share what I’m learning, my weekly newsletter covers building mobile apps for Rails businesses.