GrannyCare — AI-Powered Eldercare Companion
Inspiration
Elderly family members living alone face daily challenges: remembering medications, maintaining social connection, and getting help in emergencies. Existing solutions are either too complex (smartphone apps with tiny buttons) or too impersonal (basic pill reminders). GrannyCare was built to bridge the digital divide for seniors — a single-tap interface that feels familiar, not intimidating.
What it does
- 1-Click Mood Check-Ins — "Feeling Good / Okay / Not Well" buttons logged to a personal health timeline
- Medication Schedule & Tracking — View daily meds, mark as taken, see pending vs completed at a glance
- SOS Emergency Alert — One big red button triggers alerts to family contacts with the user's location and status
- Elderly Mode — Extra-large text, prominent buttons, simplified layout, pulsing SOS glow for users with visual/motor impairments
- Health Insights Dashboard — Check-in history, missed medication alerts, adherence stats
- Responsive Design — Works on phones, tablets, and laptops with fluid layout adaptation
How we built it
Stack: Jaclang 0.15.2, Vite dev server, CL/JSX frontend, in-memory graph database
Architecture: A single file (main.jac) containing:
| Layer | Components |
|---|---|
| Nodes | UserProfile, MedicationNode, CheckInNode — graph entities with has fields |
| Walkers | 12 walker:pub endpoints — CRUD for profile, medications, check-ins, contacts, SOS |
| Frontend | Single to cl: def:pub app() with boolean-flag conditional view switching ({show_home and <View/>}) |
| Styling | CSS injected via document.createElement("style") — Stitch design tokens, single-line string |
Views: 3 tab-based screens (Home, Health, Elderly) sharing a bottom navigation bar. State managed via has variables toggled by async def handler functions that call walkers via root spawn.
Challenges we ran into
Jaclang's CL/JSX parser has strict constraints that required workarounds:
- No variable-assigned JSX — JSX cannot be stored in variables; all views must be inline in a single
returnstatement - No
if/returnbranching — Use{boolean_flag and <View/>}pattern instead - No
else if— Jac uses Python-styleelif - No Python ternary —
x if cond else ydoesn't work; usecond and x or y - No
enumerate()in list comprehensions —for x in listonly, no tuple unpacking stylemust be an object —style={{marginLeft: "8px"}}, notstyle="margin-left:8px"new Date()syntax — Requiresnew(Date)which compiles toReflect.construct(Date, [])- CSS must be single-line — Multi-line strings break the parser; inject via DOM API
- Lambda handlers work in flat JSX —
onClick={lambda -> None { fn(); }}works in direct return JSX but not when nested in certain conditional patterns
Accomplishments that we're proud of
- All 3 Stitch-matched screens compile and serve with zero errors
- 12 pub walkers all respond correctly via the Jac API server
- Responsive layout adapts from 480px phones to 960px desktop
- SOS button with pulsing
@keyframes shglow animation - Full Material Symbols icon set integrated with font-variation-settings
- Stitch design tokens faithfully reproduced:
#06644aprimary, Literata/Nunito Sans/Lora fonts, correct component spacing
What we learned
- Jac CL/JSX is viable for single-file applications but has sharp edges — test compilation early and often
- Boolean-flag conditional rendering (
{flag and <View/>}) is a robust pattern that works despite parser limitations - CSS injection via DOM is the only reliable styling approach since the JSX parser cannot handle
<style>tags Reflect.constructvs directnew— Jac's portable constructor system handles this correctly when usingnew(Target)syntax- Cascade errors in the parser make debugging tricky: one syntax error at the top can produce 50+ misleading errors downstream
What's next for GrannyCare
- Push notifications for missed medications via browser Notification API
- Real-time clock in Elderly Mode with live
setIntervalupdates - Family caregiver dashboard — separate view for family members to monitor check-ins and alerts
- Voice assistant integration — "Hey GrannyCare, I took my aspirin" using Web Speech API
- Pill camera refill detection — ML-powered image recognition to detect low pill bottles
- Offline mode — Service worker caching for areas with unreliable connectivity
- Multi-language support — Hindi, Tamil, Bengali, and other Indian languages
Built With
- jac
Log in or sign up for Devpost to join the conversation.