Back
HealthFactor app logo

I made an app to learn React Native. It's harder than I thought.

I've been trying to build apps for mobile for a while now, and I always tried to do it with PWAs, but if you know what PWAs are, you probably know that they ABSOLUTELY SUCK.

When I first learned about PWAs, I thought they were the future and every single company would have one. My mistake. No one uses PWAs, and there's a reason for that.

What's plan B? I know React and want apps, so... Pedro, think... Oh yeah, React Native! So I dove in to learn it.

The app (the idea)

The app is called HealthFactor, and it's supposed to be the OS my body never shipped with. The idea is simple but powerful:

I want to track every single metric of my health. Yes, this is complex, but if we start small, we can always build on top of it.

PS: It's 2026, so of course the app will be AI-powered.

HealthFactor app logoTap to zoom

First thing to track: what's going into my body. Medications and supplements, with a cycle system when you need on/off patterns. Register it, set a schedule, and the app reminds you and logs everything.

The second big thing is a that can query and modify all your app data, understands basically everything health-related, and it

Then, we need to understand how your body is reacting to what you're doing, and for that, we have to track body metrics:

  1. Tracking basic body metrics: Weight, BMI, body fat, muscle mass, basically everything a bioimpedance scale spits out. I have one at home, so the plan is simple: use it, download the PDF, feed it to the AI, done.
  2. Tracking health metrics: I have no idea what to call this, so "health metrics" it is. Testosterone, estrogen, cortisol, all that stuff from your blood tests. You know those horrible PDFs they give you with 40 tests and one result per page? Yeah, I just want to dump those at the AI and have it sort everything out.

Both the medication tracker and health metrics are historical. They're built so you can ask "what was I taking 3 months ago and how was it affecting me?" and actually get the answer in under 5 minutes.

We also track your feelings, because knowing "every time I take X I get very Y" is kind of useful.

The app (what is there today)

HealthFactor app logoTap to zoom

Ok, everything is perfect in a perfect world. But what is there RIGHT NOW?

Well, not much to be honest. The hardest parts are there, but feature-wise we are still at the beggining. I've spent a lot of time learning how to make a good app instead of... Well... Making the app... But it turned out good!

The meds/supplements system is alive and kicking, with .

We can:

  1. Add a medication or supplement.
  2. Pick the icon, color, form, strength, and a dozen other things you didn't know you needed, topped off by the nightmare that is the schedule.
  3. Mark whether you actually took it or completely forgot like a normal human.

The app has tons of small features, but I'll spare you the tour and pick just one for show and tell: the one that took me the longest to build. The schedule.

The schedule

I don't do things because they're easy. I do them because .

I thought this would be the easiest problem the app would solve. Turns out it's probably the hardest one, and I'm super proud I figured it out.

HealthFactor app logoTap to zoom

Like everything, it started "simple":

  • You take it every day at 9AM? Easy, done.

  • 2 pills at 9AM and 3 at 9PM? A little harder, but fine.

  • A cycle of 1 day on, 1 day off? Sheesh. Fine, let's try.

  • 3 months, 1 day on/off cycle, PLUS an extra dose on days 1, 15, and 30 every month? Bro, are you serious?? Fine. But that's the LAST THING!!!!

Every new feature spawned another, for weeks, maybe months. But it's in good shape now.

So, how do you implement a schedule?

Obviously you just save a record for every single occurrence, right? WRONG. Dumbest idea ever. We need to define rules for this recurrence.

Hmmm... Rules for recurrence... Recurrence Rules... RRule?! THAT'S IT, WE'RE USING RRULE!

RRule

RRule lets you define a recurrence rule, duh, and generate N occurrences past or future from a single rule. No need to save millions of records. Just save the RRule and it creates everything on the fly. Pretty smart.

But here's the thing: RRule is far from perfect for our use case, and it's missing a lot of features...

So I implemented all the missing features myself. The RRule patch is now 1000+ lines, every single one adding a feature or fixing a bug.

Here are some of the features I implemented:

  1. A rule can have multiple specific hours. The old behavior was broken: provide hours 9 and 21, minutes 00 and 30, and it'd happily generate 09:00, 09:30, 21:00, and 21:30. Great. My patch lets you define exact hour-minute pairs like 09:00 and 21:30, so occurrences only fire at those times.
  2. An occurrence can have "counts", metadata that lets you say "at 21:30, take 3 instead of 1". Per-hour counts range from 0.5 to 99.
  3. A rule can have a , defining when it's active vs. inactive. 1 day on, 1 day off. Works for days, weeks, months, and years.
  4. Not only cycles but also intervals. Intervals are basically like cycles but simpler. Why have both?
  5. A rule can be daily, weekly, monthly, or yearly, with specific days.
  6. A rule auto-generates a human-readable description in both Portuguese and English, like "Every day, at 09:00 and 21:30". Every custom field we added gets reflected in the text, so you can validate your rule in real time.

This lets me generate pretty much any rule I can think of: multiple hours, cycles, intervals, you name it.

And yes, each medication supports multiple rules, because one schedule is never enough.

But what if I change my timezone? AAAAAAAAAAAAAAAAAAAAAA

Timezones

I completely forgot timezones existed. But while developing the schedules, it hit me: if the user changes timezones, the whole app breaks. And if we don't make everything timezone-aware, the server and client can't generate the same rules.

This, of course, made me lose my mind, and I stopped developing the app for a few weeks because I. Hate. Timezones.

I've been avoiding timezones for a long, long time, because I once heard: if you can avoid them, do it. Don't think twice.

So, what is the problem with timezones? Well, , like I can't even count all of them, but for us, there's only a single annoying problem:

Store timezone-agnostic values as plain strings (like "2026-04-20 09:00"), but also store timestamps for every action. Then, any time something date-related comes up, convert the string or timestamp to the correct timezone, do the work, and convert back. Every. Single. Time.

This is extremely annoying and can cause

But ok, game is game, I need to do that, so It wasn't a pleasant experience and I'm not glad that I had to do it.

Versioning

HealthFactor app logoTap to zoom

So, you took it every day at 9AM for 3 months, huh? Now you want to change it to 10AM? Why would you do that? Congratulations, now you broke the whole history of your medication!!

This is what I would say to you

Versions, versions everywhere. Changed from 50mg to 100mg? New version. Different time? New version. Tablet instead of a pill? New version. Everything is a new version. Which means you can't delete anything!!

Well, that's a lie :) there are rules for deletion. Set it to 9AM and changed your mind 5 minutes later? We're not keeping both versions, one clearly wrong with no logs and the other correct.

But what if you set it to 9AM daily, then update it to 10AM the next day at 10:30? Did you already log the 9AM dose? Do we preserve that "wrong" occurrence? Yes, this is the kind of tiny detail we had to think about.

So yeah, there are rules for deletion and archiving.

Notifications

HealthFactor app logo

You take it every day at 9AM, but are you really going to open the app every day just to log it? Modern , let's use that!!

Well, it's not so simple... Expo recently added Expo Widgets, and it's cool, it's a way to create Live Activities without Swift code, but at what cost? Well, basically, you can't do anything with it :)

Want interactivity? None. A button that calls your server? Nope. Control the Live Activity from your server? Of course not, you silly little React developer :)

So, I had to go through hell, where no one ever wants to go: I had to open XCode

Swift (SwiftUI specifically) is great. Xcode is a disaster, but the language itself is genuinely great. With it, I built a Dynamic Island activity and a Live Activity in the notifications, both with buttons to log medications as taken or skipped without even opening the app. App closed? Doesn't matter.

HealthFactor live activity in Dynamic Island and notification

You can also tap the notification to open the app and log it manually if you prefer to add details.

But when does this trigger? We have the RRule, so :

  1. A schedule table triggers a mutation every time a stored timestamp is reached, acting as the heartbeat of the whole flow.
  2. The mutation fires an event to open the live activity, kicking off the chain.
  3. The server catches that event and issues the token via APNS, which is what actually opens the live activity on the device.
  4. The live activity briefly wakes the app, just long enough to generate the push-to-update token and ship it back up to the server.
  5. The server stores the token. From this point on, it can update or close the activity whenever it wants, without needing the app to be open.

Easy, right? Wrong. Almost 2 days of pure suffering. Turns out Bun has a well-documented bug where it can't communicate with APNS over HTTP/2, so I had to build a

But I did it. I implemented it. I made it work. And it's a really cool feature.

This is an app you'd open once a day if you're a power user, or once a week/month if you're a typical user.

By the way, while writing this, I got a notification reminding me to take a fake medication. The Dynamic Island, the notification, the whole thing was beautiful.

The result

In the end, everything seems to be working perfectly.

Honestly, I'm stupidly proud of pulling this off. This was easily one of the hardest things I've ever built, and the brutal part is that it had no right to be. I was trying to ship a cutting-edge app while simultaneously figuring out how to build a basic one, except the "basic" one kept revealing new layers of hidden complexity like some kind of evil onion.

It looked simple. It absolutely was not. Lesson learned, I guess. Now I understand why Apple Health sucks.

The future

Next up: final polishing, making everything look gorgeous, and shipping this thing to the App Store before I lose my mind.

There are still a few optimizations to knock out and the main flows could use some love, but honestly, when AI is holding your hand through every interaction, do the manual flows even need to be that good? Yes, of course they do, we are not going to deploy slop, but it's not the focus right now. First, get features out the door.

After that, we can focus on the details as much as we want.

Oh, and I'm open to work. If you need someone who digs into the ugly details, refuses to give up on hard problems, and actually gets stuff out the door, hit me up.

Some Extra assets

Every toast appears on the dynamic island :) this is a really nice touch to make the app feel modern.

HealthFactor dynamic island toast

Basically everything that is interactive has a context menu to make it easy to use :)

HealthFactor context menu

I needed to make some fake data. I was going to ask ChatGPT and manually add it, but then I thought: I have an AI assistant integrated in the app, why not use it? And it NAILED IT. What If I told you that this happened in less than 20 seconds? It created everything and generated a report in less than 20 seconds.

HealthFactor context menuHealthFactor context menu