A decentralized, browser-based medicine reminder system that helps patients, caregivers, and elderly users take their medications on time — with scheduled notifications, AI-assisted drug lookup, adherence analytics, and a full user profile management system, all backed by the Internet Computer Protocol.
- Overview
- Features
- Tech Stack
- System Architecture
- Authentication
- Medicine Lookup
- Reminder Notifications
- User Profile Management
- Analytics and Adherence Tracking
- Data Storage
- Getting Started
- Project Structure
- Deployment
- Known Issues and Fixes
- Future Enhancements
- License
Medication non-adherence is a critical public health problem. Studies consistently show that nearly 50% of patients with chronic conditions do not take their medicines as prescribed, contributing to disease complications, avoidable hospitalizations, and increased healthcare costs. The challenge is especially acute among elderly patients, individuals managing multiple concurrent medications, and caregivers coordinating schedules for others.
MediRemind addresses this problem by providing a smart, lightweight, and privacy-first web application that:
- Allows users to register and create personalized medicine reminder schedules with specific dosages and times.
- Delivers real-time browser popup notifications and voice alerts (via the Web Speech API) at the scheduled time, without requiring any server-side push infrastructure.
- Gives users instant access to AI-summarized drug information from the OpenFDA database directly within the app.
- Tracks adherence over time through a 7-day bar chart, streak counter, and overall adherence percentage, motivating consistent behavior.
- Stores all data securely and permanently on the Internet Computer Protocol (ICP) blockchain — no centralized cloud server, no third-party database, and no reliance on local browser storage.
The application targets three primary user groups:
- Patients managing chronic conditions (diabetes, hypertension, cardiovascular disease) who need reliable daily dose reminders.
- Caregivers who coordinate medication schedules for family members or patients in their care.
- Elderly users who benefit from the combination of browser popup alerts, voice reminders, and a simple, well-structured interface.
- Schedule medicine reminders with medicine name, dosage, frequency, and a specific daily time.
- Edit and delete existing reminders from the dashboard.
- Mark doses as taken or missed directly from the reminder interface.
- Real-time browser popup notifications at the scheduled dose time (requires notification permission).
- Voice alert via the Web Speech API that reads the reminder aloud (e.g., "Time to take your Metformin 500mg").
- Pulsing green dot in the application header confirms that the notification monitoring system is actively running.
- Search any medicine by name to retrieve structured drug label data from the OpenFDA API (~200ms average response).
- AI-generated plain-language summary produced in parallel using the Hugging Face
facebook/bart-large-cnnmodel. - In production, medicine search is routed through the backend canister's ICP HTTPS outcalls to bypass browser Content Security Policy restrictions.
- Local offline fallback database of 8 common medicines (Metformin, Lisinopril, Atorvastatin, Omeprazole, Amoxicillin, Ibuprofen, Paracetamol, Amlodipine) used if external APIs are unavailable.
- Dedicated Profile tab in the main navigation, also accessible via a clickable avatar icon in the application header.
- Editable profile card with fields: Full Name, Email, Age, Gender, and Locality / Address.
- Profile photo upload using a simple file picker backed by ICP Blob Storage; the photo is displayed in both the header avatar and the profile card.
- Medical Records section with three fully editable sub-sections: Doctor Guidance (doctor name and prescribed treatment), Checkup Reports (visit date and notes), and Medication Reports (auto-populated from active reminders, read-only).
- "Last Updated" timestamp displayed on the profile card after any save.
- Logout button inside the Profile tab that clears the session and redirects to the login page.
- 7-day SVG bar chart showing daily dose completion rate.
- Streak tracker with flame animation showing consecutive days of full adherence.
- Overall adherence percentage calculated from the dose log.
- Filterable dose history log showing all taken and missed doses with timestamps.
- CSV export of the complete dose log for sharing with a healthcare provider.
- Dark mode toggle for comfortable use in low-light environments.
- Fully responsive design supporting desktop, tablet, and mobile browsers.
- Registration form collects Full Name, Email, Age, Gender, Locality, Username, and Password — all fields present in the profile edit section, so the profile is populated from day one.
| Layer | Technology | Purpose |
|---|---|---|
| UI Framework | React 19 + TypeScript + Vite | Component-based SPA with compile-time type safety |
| Styling | Tailwind CSS | Utility-first responsive design and dark mode |
| Graphics | SVG (Scalable Vector Graphics) | Adherence bar charts, flame animations, inline icons |
| Scripting | JavaScript ES6+ | Notification scheduling, Web Speech API, PBKDF2 crypto, CSV export |
| Backend Language | Motoko | Smart contract logic on the Internet Computer |
| Backend Platform | Internet Computer Protocol (ICP) | Decentralized hosting, canister-based data storage, HTTPS outcalls |
| Authentication | Internet Identity + PBKDF2 / Ed25519 | Wallet-based and username/password login with derived IC identity |
| File Storage | ICP Blob Storage | Profile photo upload and retrieval |
| Medicine Data | OpenFDA API | Real-time drug label and dosage information |
| AI Summarization | Hugging Face (facebook/bart-large-cnn) |
Plain-language AI summaries of raw FDA drug labels |
| External API Proxy | ICP HTTPS Outcalls | Routes API requests through the canister in production to bypass CSP |
| Build Tooling | Vite + pnpm | Dev server, hot module replacement, production bundling |
| Package Manager (Backend) | Mops | Motoko dependency management |
MediRemind uses a decentralized full-stack architecture hosted entirely on the ICP network. The frontend is served from an ICP asset canister and communicates with the backend Motoko canister through the ICP Agent library over HTTPS.
User Browser
|
+-- React Frontend (ICP Asset Canister)
| |
| +-- ICP Agent (HTTPS) --------> Motoko Backend Canister (ICP Network)
| |
| +-- User Store (Stable Memory)
| +-- Reminders Store (Stable Memory)
| +-- Dose Log Store (Stable Memory)
| +-- Medical Records Store (Stable Memory)
| |
| +-- HTTPS Outcalls
| |
| +-- OpenFDA API
| +-- Hugging Face API
|
+-- Direct Browser Fetch (Dev / Draft) -> OpenFDA API (~200ms)
| Layer | Technology | Responsibility |
|---|---|---|
| Presentation | React, TypeScript, Tailwind CSS, SVG, Web APIs | UI rendering, user input, state display, notification scheduling |
| Application Logic | TypeScript, ICP Agent JS, PBKDF2, Ed25519, Web Speech API | Authentication, identity derivation, backend actor creation, medicine search orchestration |
| Business Logic | Motoko, ICP Canister SDK | Access control, CRUD operations, dose log management, HTTPS outcall proxy |
| Data Persistence | ICP Stable Memory | Permanent, replicated, tamper-resistant data storage across ICP subnet nodes |
MediRemind supports two authentication methods. Both produce a valid Internet Computer principal that is used to sign all backend canister calls.
| Method | Mechanism | Use Case |
|---|---|---|
| Username + Password | User credentials are passed through PBKDF2 (100,000 iterations, SHA-256) using the browser's SubtleCrypto API to deterministically derive an Ed25519 keypair. This keypair becomes the user's unique IC principal. |
General users unfamiliar with Web3 workflows |
| Internet Identity | ICP's native browser-based decentralized authentication. Uses a hardware authenticator, fingerprint sensor, or device PIN to produce a unique IC identity anchor. | Web3-native users |
AuthContext(React Context API) holds the authenticated state globally across all components. It is always present inmain.tsxas the outermost provider wrapper, preventing crashes caused byuseAuth()calls outside of context.- The
useActorcustom hook creates the authenticated backend actor usingiiIdentity ?? passwordIdentity, ensuring that password-login users receive a properly authenticated actor even when Internet Identity is not active. - The password-derived identity seed is stored in
sessionStorageto survive page refreshes within a browser session. It is cleared automatically when the tab is closed or the user logs out.
The medicine information lookup feature uses a layered strategy to balance speed, reliability, and production compatibility:
-
Direct OpenFDA fetch (primary) — The frontend performs a direct
fetch()tohttps://api.fda.gov/drug/label.jsonfrom the browser. Average response time is approximately 200ms. This path is used in development and draft environments. -
Hugging Face AI summary (parallel) — While the OpenFDA response is loading, a concurrent request is made to the Hugging Face Inference API using the
facebook/bart-large-cnnmodel. The model condenses the raw FDA drug label text into a short, plain-language paragraph suitable for non-medical users. -
Backend canister HTTPS outcall (production fallback) — In production deployments, browser Content Security Policy (CSP) headers may block direct fetch calls to external APIs. In this case, the same requests are routed through the Motoko backend canister's ICP HTTPS outcall mechanism, which proxies the requests from within the ICP network and returns the results to the frontend. Typical response time via this path is 4–8 seconds.
-
Local offline database (final fallback) — If both the direct fetch and the backend outcall fail (e.g., due to network unavailability or API downtime), a local static database of 8 common medicines is used to return basic information.
All notification scheduling runs entirely within the user's browser. No server-side push infrastructure is required.
- On application load,
useReminderNotificationsrequests browser notification permission from the user. - A
setIntervalloop runs every 30 seconds in the background while the page is open. - Each tick retrieves the current local time in
HH:MMformat and compares it against the scheduled time of all active reminders. - When a match is found, the system fires:
- A browser Notification popup displaying the medicine name and dosage.
- A voice alert via
window.speechSynthesisreading the reminder aloud. - A console log entry for debugging.
sessionStorageis used to track which reminders have already fired in the current minute, preventing duplicate alerts.- If the user has not granted notification permission, the system falls back to
window.alert()to ensure the reminder is never silently missed.
Reminder notifications only trigger while the browser tab is open and active. Background or service worker notification support is not yet implemented. The pulsing green dot in the application header provides visual confirmation that the notification monitoring system is actively running in the current tab.
The profile section is accessible from two locations:
- The dedicated Profile tab in the main navigation bar.
- The clickable avatar icon in the application header, which switches the active view to the Profile tab.
The profile card displays and allows editing of the following fields:
| Field | Type | Notes |
|---|---|---|
| Full Name | Text | Required |
| Text | Required | |
| Age | Number | Optional |
| Gender | Select | Optional |
| Locality / Address | Text | Optional |
| Profile Photo | Image | Optional — uploaded via ICP Blob Storage |
| Last Updated | Timestamp | Auto-set on save |
| Section | Content | Editable |
|---|---|---|
| Doctor Guidance | Doctor name and prescribed treatment details | Yes — free text |
| Checkup Reports | Visit date and clinical notes | Yes — free text |
| Medication Reports | List of active reminders with dosage and time | No — auto-populated from reminder data |
The Logout button in the Profile tab clears the current session (removes the password identity seed from sessionStorage and resets the AuthContext state), then redirects the user to the login page.
| Feature | Description |
|---|---|
| 7-Day SVG Bar Chart | Displays daily dose completion percentage as a bar chart rendered with inline SVG for the past seven days. |
| Streak Tracker | Counts consecutive days on which all scheduled doses were marked as taken. Displays a flame animation when an active streak is present. |
| Adherence Percentage | Calculates the overall ratio of taken doses to total scheduled doses across the user's full dose log history. |
| Dose History Log | A scrollable, filterable list of all dose actions (taken or missed) with medicine name, scheduled time, and action timestamp. |
| CSV Export | Generates a comma-separated file from the dose log and triggers a browser download, suitable for sharing with a healthcare provider. |
All persistent data is stored in the Motoko backend canister's ICP stable memory. This storage survives canister upgrades, is replicated across all nodes in the ICP subnet for fault tolerance, and is accessible only through the canister's own code.
No localStorage, sessionStorage (except for the temporary session identity seed), cookies, or third-party databases are used for application data.
| Collection | Key | Key Fields |
|---|---|---|
| Users | IC Principal | username, passwordHash, fullName, email, age, gender, locality, profilePhotoId, lastUpdated |
| Reminders | IC Principal + Reminder ID | medicineName, dosage, frequency, scheduledTime (HH:MM), isActive, createdAt |
| Dose Log | IC Principal + Log ID | reminderId, medicineName, scheduledTime, actionTime, status (taken | missed) |
| Medical Records | IC Principal | doctorName, prescribedTreatment, checkupDate, checkupNotes, lastUpdated |
- Node.js v18 or higher
- pnpm v8 or higher
- DFINITY Canister SDK (DFX) — installation guide
- Mops (Motoko package manager) — installed automatically via
npm install -g ic-mops
Frontend
cd src/frontend
pnpm install --prefer-offlineBackend
cd src/backend
mops installThis step produces the TypeScript type definitions (backend.d.ts) and the runtime actor wrapper (backend.ts) that allow the frontend to call backend methods with full type safety.
# Run from the project root
pnpm bindgenThis step must be re-run whenever the Motoko canister interface changes.
# Start the ICP local replica
dfx start --background
# Deploy canisters to the local replica
dfx deploy
# Start the Vite development server (from src/frontend/)
cd src/frontend
pnpm devThe application will be available at http://localhost:5173 by default.
# Frontend type check
cd src/frontend
pnpm typecheck
# Backend type check
cd src/backend
mops check --fix# Frontend production build
cd src/frontend
pnpm buildsmart-medicine-reminder/
+-- src/
| +-- frontend/
| | +-- src/
| | | +-- components/ # Shared UI components (Layout, Header, etc.)
| | | +-- context/ # AuthContext — global authentication state
| | | +-- hooks/ # Custom React hooks (useQueries, useReminderNotifications)
| | | +-- pages/ # One file per application route/tab
| | | +-- services/ # Medicine search service, CSV export, identity derivation
| | | +-- App.tsx # Router configuration and provider wrappers
| | | +-- main.tsx # Application entry point — AuthProvider always present here
| | +-- public/
| | | +-- assets/
| | | +-- images/ # Static image assets
| | +-- index.html
| | +-- tailwind.config.js
| | +-- tsconfig.json
| | +-- vite.config.ts
| +-- backend/
| +-- main.mo # Motoko canister entry point and public API surface
| +-- types/ # Shared Motoko type definitions
| +-- mops.toml # Motoko package manifest
+-- dfx.json # DFX canister and network configuration
+-- package.json # Root package.json (bindgen script)
+-- README.md
MediRemind is deployed on the Internet Computer Protocol network via the Caffeine AI Platform, which handles canister scaffolding, automated TypeScript binding generation, and one-click production deployment.
GitHub Repository: https://github.com/dev-dipeshkumar/smart-medicine-reminder
dfx deploy --network icBefore deploying, ensure:
- The local replica is stopped (
dfx stop). - You have a cycles wallet with sufficient cycles for canister creation and initial storage.
pnpm bindgenhas been run after any backend interface changes.- The frontend production build (
pnpm build) completes without errors.
The following recurring bugs were identified and permanently resolved during development.
| Issue | Root Cause | Fix Applied |
|---|---|---|
| Blank white screen on app load | AuthProvider was missing from main.tsx, causing useAuth() to throw an unhandled error immediately on mount, crashing the entire React tree silently. |
AuthProvider is now always the outermost wrapper in main.tsx. This is a protected file — modifications must be reviewed carefully to prevent regression. |
| "Failed to create reminder" on submission | useActor was only reading iiIdentity and ignoring the password-derived identity entirely. Backend calls were sent anonymously and rejected by the canister's access control. |
useActor now uses iiIdentity ?? passwordIdentity, ensuring password-login users receive a correctly authenticated actor. |
| "Failed to update profile" in all three Profile sections | Same root cause as above — anonymous backend calls were rejected by the canister. | Same fix: useActor now always uses the available authenticated identity. |
| Daily progress section not updating after marking a dose | Backend calls for the progress update were made anonymously (same identity issue), returning empty data silently. | Resolved by the identity fix above; progress now updates immediately after a dose action. |
- Progressive Web App / Mobile — Package the application as a PWA or native mobile application (iOS and Android) for offline access and home screen installation.
- Service Worker Background Reminders — Implement a service worker to fire notifications even when the browser tab is closed or the device is locked, removing the current requirement for an open tab.
- AI-Powered Smart Scheduling — Use machine learning to analyze a user's adherence history and automatically suggest optimal reminder times based on past behavior patterns.
- Doctor and Pharmacy Integration — Allow healthcare providers to push prescriptions and dosage instructions directly to a patient's MediRemind account, reducing manual data entry.
- Smart Wearable Support — Integrate with wearable devices (smartwatches, fitness bands) to deliver haptic and display alerts directly on the wrist.
- Email Notification Backup — Send a backup email notification when a scheduled dose time passes without the user marking it as taken, for users who may not have the browser open.
- Multi-Language Support — Localize the interface and voice alerts into regional languages to serve a broader patient population, including non-English-speaking elderly users.
- Prescription Image Upload — Allow users to photograph and upload a prescription document, storing it in ICP Blob Storage and associating it with the corresponding reminder record.
This project is developed as a B.Tech Computer Science Engineering final year project and is intended for academic demonstration purposes.
Built with Caffeine AI on the Internet Computer Protocol.