It's been three days since I last posted anything. Since I started interacting with Claude IA and discovered the wonders of Claude Code, I've been focusing on creating and building applications that aim to improve people's productivity or routines, trying in a way to offer high-performance applications at cost price.
The idea is to always try to make things cost R$10, whether it's a lifetime purchase or a premium subscription. Perhaps I can make something more complex for R$20, but for me, I want quantity instead of high value, at least for now in the beginning.
The browser extension is called "Medicine Time" and I'm still finishing building it, fixing some details and things like that. I still need to publish it on the Chrome Web Store and I think they'll accept it without problems. After that, it's time to move on to the mobile app, focusing on Android and then, if I can somehow manage it, iOS.
The summary below was created by CLAUDE, with some revisions and changes on my part!
- The Idea
It seems simple: taking medication at the right time. But anyone undergoing ongoing treatment—or caring for someone who does—knows it's harder than it looks. Mobile apps abound, but I wanted something that would stay where I spend most of my time: in the browser, working.
A Chrome extension that triggers alarms, shows operating system notifications, plays a sound, and displays an animated banner on the pages I'm browsing. All synchronized with my Google account, working on any computer.
- The Stack
The project is a monorepo with three packages:
packages/extension — the Chrome extension itself, made with React + TypeScript + Vite
packages/shared — shared library with types, business logic, and access to Firebase
packages/functions — Firebase Cloud Functions for payment processing
The backend is 100% Firebase: Firestore for data, Authentication with Google, Cloud Functions for Stripe, Hosting for payment return pages.
- What was built
Medication Registration
Complete form with name, dosage (tablet, drop, capsule, mL, sachet, ampoule), frequency (4h, 6h, 8h, 12h or once a day), treatment duration (3 days to continuous use) and start time with date and time selector. Each medication has a color for visual identification.
Alarm System
The most complex part. Chrome has an alarm API with a minimum delay of 60 seconds, but the big challenge was a race condition: if the service worker is killed by Chrome (which happens frequently with Manifest V3) and revived exactly when an alarm triggers, the notification data needs to be in storage before the alarm is created—not after. I fixed this by saving everything to chrome.storage.local first and only then registering the alarms.
Three-Layered Notifications
When it's time for your medication, three things happen simultaneously:
-
Operating system notification — with "✅ Taken!" and "⏰ Remind me in 15 min" buttons
-
Nine beep sounds — three groups of three notes (C-E-G) played via Web Audio API in an offscreen document, since service workers don't have access to audio
-
Sliding visual toast — appears in the lower right corner of all open tabs, even tabs that were opened before the extension was installed (solved by injecting the toast directly into the DOM via executeScript)
-
Dynamic badge: The extension icon displays a red number with the number of doses remaining. It persists even if the service worker is restarted by Chrome — restored by reading the storage at startup.
- 15-Minute Snooze
Clicking "Remind me in 15 min" creates a new Chrome alarm with a special prefix and saves the dose data. When it goes off, it displays the notification normally.
- Drag and Drop
The medication list supports drag-and-drop reordering, with the order saved in localStorage.
- Dose History
Every time the user clicks "Taken!" — whether on the popup banner, the tab toast, or the OS notification button — the dose is recorded in Firestore with the medication name, quantity, color, and exact time. The history is displayed grouped by date. Free plan: last 7 days. Premium plan: 90 days.
- Light and dark theme
Toggle in header, preference saved in localStorage.
- Terms of use
Full modal on the login screen with eight sections.
Monetization with Stripe
I implemented a freemium model:
- Free plan:
Up to 3 registered medications
Reminder notifications
Synchronization via Google on any device
History of the last 7 days
- Premium plan (R$9.90/month or R$79.90/year):
Unlimited medications
History of the last 90 days
Family sharing (holder + 1 guest)
Export report in PDF for the doctor (coming soon)
Payment uses hosted Stripe Checkout — the extension opens a tab with the Stripe payment page via chrome.tabs.create, the Cloud Function creates the session, the Stripe webhook confirms and updates Firestore in real time. The popup detects the change via onSnapshot and instantly unlocks premium features.
- Family Sharing
One of the features I most enjoyed designing. The premium account holder generates a 6-digit code and shares it with a family member or caregiver. The guest enters the code and can then see the account holder's medications on their own home screen—in read-only mode.
The technical challenge: I needed a separate inviteCodes collection in Firestore with public readability for authenticated users. Searching directly in users by field would be blocked by security rules (which only allow each user to read their own profile).
- Interesting bugs I solved
Race condition in alarms: data saved after creating the alarm caused notifications without content when the service worker revived. Solution: reverse the order, always save before.
Toast not appearing in old tabs: after reloading the extension, open tabs retained window.__hdrToastLoaded = true from a dead listener. Solution: in the fallback, inject the toast directly into the DOM via executeScript with a self-contained function, without depending on any previous state.
Today's date showing tomorrow: new Date().toISOString() returns UTC — in UTC-3, at 10 PM "today" in UTC is already "tomorrow". Solution: use getFullYear(), getMonth(), getDate() to construct the local date.
Double-log in history: when clicking "I took it!" on the popup banner, the log was saved twice — once directly by the popup and again via the service worker queue. Solution: Separate the two paths — popup saves directly, service worker queues only when acting independently (OS notification).
- The Process
All development was done in partnership with Claude Code, from Anthropic. It's an AI tool that runs in the terminal and has access to the file system, being able to read, edit and create files, run commands, search the code and reason about architecture.
- Next Steps
Export PDF report of dose history (premium feature)
Treatment adherence statistics
Support for multiple profiles (for caregivers)
If you have someone in your family who needs help remembering their medication, or if you yourself have ongoing treatment, this extension was made with you in mind.
Medication Time — because taking care of your health starts with consistency.
Built with React, TypeScript, Firebase, Stripe and Chrome Extensions Manifest V3.
That's it, chasing after creating something profitable and monetizing it, but obviously delivering a decent product as well, that's very interesting and I've been focusing on that instead of Hive for now.