Built with Ruby Native

StatusGator icon

Two years stuck behind a second codebase, now shipping from Rails.

StatusGator tells IT teams when their vendors go down, often before the vendor does, across 7,600+ monitored services. The team is remote, profitable, TinySeed-backed, and all-in on Rails. Two of them write code.

“The fact that all this stuff is in our repo, using the stuff we already know, and we can just edit it, that's huge.”
Colin Bartlett

Colin Bartlett

Co-founder, StatusGator

The app that kept not shipping

StatusGator's product is the alert. When Zoom or AWS goes down, an IT admin finds out from StatusGator: in Slack, by email, through PagerDuty. But customers kept asking for an app because they wanted push notifications.

One of the team's developers even built a prototype, in Flutter, as a side project. "It was really just an experiment," Colin says. "It worked, but it didn't have any of our normal product development cycle in it."

But the prototype did prove that the idea was right:

When SendGrid went down and I got a push notification on my phone: perfect. That's exactly what I wanted.
Colin Bartlett

Nobody else on the team knew Flutter or Dart, and any attempt to fix that didn't get far. "We took some time to get everybody educated on Dart and Flutter," Colin says. "But we never even got past the environment set up."

Even AI-assisted development didn't help much. Their designer works in Figma and the team ships HAML and Tailwind, none of that carried over. "We don't even have our Tailwind styles in Flutter. And we'd have to maintain all of it as our tooling evolves. This is a lot of work for something that's just one of 20+ notification methods."

So the app sat, by Colin's estimate, for about two years.

None of the other options were any good

The requests didn't stop, so the team started pricing ways to ship the prototype. They had a number in their heads. "How much could this simple app possibly cost? We could definitely build this for 10K, right?" Then a quote for a fully custom build came back. "It was definitely more than that. That's a lot of money, and we still wouldn't know how to maintain it."

And the maintenance problem was twice as expensive, because their customers needed both iOS and Android apps. "Every time we say we're working on a mobile app, the first thing customers ask is: is it on both platforms? It had to be on both."

React Native was in the running, since some of the team had shipped with it at a previous company. StatusGator's product already works as HTML and CSS. So React Native meant rebuilding all of their business logic as JSON APIs just to feed the app. And only then starting on the app's native codebases. "You had to build the APIs and then hope that was what the mobile app needed. We did not like it."

It would also have added to the stack, not simplified it. "We have no React on our whole site. We'd be introducing the fourth JavaScript framework to our stack."

The realistic path was finding a Flutter contractor to inherit the prototype. "Sunk cost fallacy being a strong thing," as Colin puts it. Nobody was excited about that.

Every option ended in the same place: a second (or third!) codebase, in a language they didn't write, that they would own forever.

One repo, every platform

Colin had seen Ruby Native in my newsletter and on LinkedIn without looking closely. When we talked about it directly, the architecture was what finally got him interested. "It's Ruby, which I like, and it's HTML, which I like. And I don't have to compile it myself, it's compiled in the cloud."

But he had two real worries. The first was depending on a young product: "The idea that it could disappear and we would have to start over is a risk for sure." Ruby Native customers get the compiled app's source code, and keep it forever. The escape hatch ships with the product, so "the risk seemed low."

The second was performance, because StatusGator's traffic spikes exactly when a big vendor goes down. In this architecture, a performance problem is a Rails problem. "It's a known problem. I know how to improve SQL performance and rendering. If it was native control performance, I would have no clue how to do that." And any fix helps the website too, because they are the same views.

I built the app with them: their designer's mockups, the Rails integration, and both store submissions. All of it Rails work, with no second codebase for it to live in: same views, same models, same repo, same deploy. After two years of not shipping, that is what finally made it shippable.

Colin expected a rougher path: "I thought maybe we'd ship something half-functional and then iterate in the App Store. There was no need. The end result was perfect."

Matching a designer's mockups is usually the safe call. Here it wasn't. The shipped app doesn't match the original Figma pixel for pixel, and Colin prefers it that way.

The designs predated any native thinking, so navigation moved into a real native tab bar and native menus instead of recreating website chrome. That is chrome nobody had to design. "What we shipped has a much more native feel than what we had designed. And the innards are still exactly how we designed."

What the team owns now

StatusGator deploys three to five times a day, and the app updates with every deploy, because almost everything in it is a Rails view. There is no "mobile" release pipeline for content changes and no app review cycle for a template tweak.

Anybody on our team can make these changes now. It's very easy to pull up a preview on your phone and try it out, and that doesn't require an App Store release. Most of this stuff does not require any release. It's kind of the dream come true.
Colin Bartlett

The proof came after handoff. Colin added haptic feedback to the notification bells himself, from Rails, with one helper:

- = button_to "Mute", mute_path(service)
+ = button_to "Mute", mute_path(service), data: native_haptic_data

No Xcode, no native development environment, no App Store release. The capability was already compiled into the shipped app, waiting for the server to ask for it, so it shipped with an ordinary Rails deploy. "Tapping the bell icon and it just vibrates your phone a little bit. That's so cool."

And the Flutter prototype? "It's gone. We'll archive the repo. It served its purpose, which was a prototype to prove it out."

Who Ruby Native is wrong for

I asked Colin who shouldn't use Ruby Native. "If you need a lot of deep native features, you might need to look elsewhere. But the vast majority of people don't need that stuff." He'd love a home screen widget showing services that are down, and that capability isn't in Ruby Native today. For a companion app whose job is a reliable push notification, nothing was missing.

For us, it's perfect. I can't imagine using a framework like React Native.
Colin Bartlett, co-founder, StatusGator

What shipped

What StatusGator's app does

Every screen is a Rails view. The native pieces come from the gem's view helpers and one YAML file.

Scan to pair

A user scans a QR code from their status page and their phone is paired. No account, no password, no sign-in screen. From the phone's camera, Universal Links and App Links open the app directly; inside the app, it is the native iOS and Android QR scanner.

Per-service notifications

Every service row has a bell. People choose exactly which services are allowed to interrupt them. Selection lives in Rails and filters server-side, in the same path that already filters email, so nobody wrote new filtering logic for mobile.

Push that opens the right screen

Tapping an outage notification opens the affected service directly. Push is one more delivery channel in Rails, alongside the email and Slack alerts they already send.

Multiple status pages

Consultants and MSPs work across several organizations. Scanning another code adds it, and switching between them is a native dropdown in the navigation bar.

Written once, native on both

Dark mode, native transitions, haptics, and the loading, empty, and error states, on iOS and Android, all rendered from the same Rails views.

Your turn

Deploy your Rails app to the app stores

StatusGator's app is their Rails app: same views, same repo, same deploy. Adding Ruby Native to yours takes a gem and a config file, then you can preview it on your phone. All without Xcode, Android Studio, or any additional codebases.