Setup and context
Staying hydrated is essential for your health, yet most of us don't track how much water we actually drink throughout the day. In this tutorial, you'll build a water intake tracker app from scratch using Rork — complete with intake logging, visual progress tracking, and smart reminders.
The app you'll create has three core features: recording water intake with quick-tap buttons, displaying daily progress with a circular progress bar, and sending periodic reminders so you never forget to hydrate. Even if you're brand new to Rork, this guide walks you through every step from writing your first prompt to polishing the final UX.
Who This Tutorial Is For
- Beginners looking to get started with Rork app development
- Anyone interested in learning the structure of a healthcare app
- Developers curious about data persistence and notifications in React Native
What You'll Build
The finished app includes these screens and features:
- Home Screen: A circular progress bar showing today's intake vs. goal, with one-tap buttons for quick logging
- History Screen: A bar chart displaying the past 7 days of water intake
- Settings Screen: Adjustable daily goal and reminder intervals
Prerequisites
All you need is a Rork account and a web browser. No prior programming experience is required, but familiarity with a few concepts will help you follow along more easily:
- Components: Building blocks of the UI (buttons, text, cards, etc.)
- State: Data the app keeps track of (like how much water you've had today)
- AsyncStorage: A mechanism to save data locally on the device
Rork's free plan lets you generate up to 5 projects per week, so feel free to experiment without any commitment.
Step 1: Create the Project and Basic UI
When creating a Rork project, your initial prompt shapes the foundation of the entire app. Enter a prompt like this:
Create a water intake tracker app.
Screens:
1. Home screen — Display today's water intake with a circular progress bar.
Quick-add buttons for 150ml / 250ml / 500ml.
2. History screen — Show past 7 days of intake as a bar chart.
3. Settings screen — Set daily goal (ml).
Design:
- Clean UI with a light blue color scheme
- Bottom tab navigation (Home / History / Settings)
Data:
- Store locally using AsyncStorageRork will automatically generate a React Native + Expo project based on this prompt. Pay attention to the tab navigation structure and how components are separated — these are patterns you'll use in every app you build.
Expected File Structure
app/
├── (tabs)/
│ ├── index.tsx # Home screen
│ ├── history.tsx # History screen
│ └── settings.tsx # Settings screen
├── _layout.tsx # Navigation config
components/
├── CircularProgress.tsx # Circular progress bar
├── QuickAddButton.tsx # Quick-add buttons
└── WeeklyChart.tsx # Weekly bar chart
stores/
└── waterStore.ts # State management (Zustand, etc.)
Step 2: Data Persistence
Water intake records need to survive app restarts, so you'll store them on the device. Rork-generated code typically uses AsyncStorage, but the data structure you define is what makes the app reliable.
Use this prompt to clearly specify your data model:
Design the data model as follows:
- WaterLog: { id: string, amount: number, timestamp: string }
- DailyRecord: { date: string, logs: WaterLog[], totalAmount: number }
- Settings: { dailyGoal: number, reminderInterval: number }
AsyncStorage keys:
- @water_logs — Daily records (last 30 days)
- @settings — User preferences
Load data from AsyncStorage on app launch and sync to state.Since AsyncStorage only stores strings, the generated code will use JSON.stringify for saving and JSON.parse for loading. Here's what the key parts look like:
// stores/waterStore.ts — core logic (expected output)
import AsyncStorage from '@react-native-async-storage/async-storage';
const STORAGE_KEY = '@water_logs';
// Save data
const saveLogs = async (logs: Record<string, DailyRecord>) => {
await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(logs));
};
// Load data
const loadLogs = async (): Promise<Record<string, DailyRecord>> => {
const data = await AsyncStorage.getItem(STORAGE_KEY);
return data ? JSON.parse(data) : {};
};For more in-depth patterns on local data handling, check out Offline-Ready Rork Apps with AsyncStorage and NetInfo for a comprehensive implementation guide.
Step 3: Building the Circular Progress Bar
The circular progress bar is the centerpiece of the home screen — it lets users see at a glance how close they are to their daily goal. Prompt Rork with these specifics:
Improve the circular progress bar on the home screen:
- Render with SVG (use react-native-svg)
- Color changes based on progress (0-50%: light blue, 50-80%: blue, 80-100%: dark blue, 100%: green)
- Display "750 / 2000 ml" in the center
- Celebration animation when goal is reached
- Smooth progress animation when values changeRork will generate a component using react-native-svg with strokeDasharray and strokeDashoffset — a performant approach for circular progress indicators.
// components/CircularProgress.tsx — expected output
import Svg, { Circle } from 'react-native-svg';
import { Animated } from 'react-native';
interface CircularProgressProps {
current: number; // Current intake
goal: number; // Daily goal
size?: number; // Component size
}
export default function CircularProgress({ current, goal, size = 200 }: CircularProgressProps) {
const radius = (size - 20) / 2;
const circumference = 2 * Math.PI * radius;
const progress = Math.min(current / goal, 1);
const strokeDashoffset = circumference * (1 - progress);
// Determine color based on progress
const getColor = () => {
if (progress >= 1) return '#22c55e'; // Green (complete)
if (progress >= 0.8) return '#1e40af'; // Dark blue
if (progress >= 0.5) return '#3b82f6'; // Blue
return '#7dd3fc'; // Light blue
};
return (
<Svg width={size} height={size}>
{/* Background circle */}
<Circle cx={size/2} cy={size/2} r={radius}
stroke="#e5e7eb" strokeWidth={10} fill="none" />
{/* Progress circle */}
<Circle cx={size/2} cy={size/2} r={radius}
stroke={getColor()} strokeWidth={10} fill="none"
strokeDasharray={circumference}
strokeDashoffset={strokeDashoffset}
strokeLinecap="round"
rotation={-90} origin={`${size/2}, ${size/2}`} />
</Svg>
);
}Step 4: Adding Reminder Notifications
Periodic hydration reminders are what transform this from a simple logger into a genuinely useful health companion. You'll use Expo's Notifications API:
Add a reminder notification feature:
- Settings screen: choose notification interval (30min / 1hr / 2hr / 3hr)
- Only send between waking hours (default: 8:00 AM - 10:00 PM)
- Notification message example: "Time to hydrate 💧 You need 750ml more to reach today's goal"
- Skip notifications on days when goal is already reached
- Use expo-notificationsNotification frequency directly impacts user experience. Too many, and they become annoying; too few, and they lose their purpose. The default 1-hour interval strikes a good balance for most users.
// utils/notifications.ts — expected output
import * as Notifications from 'expo-notifications';
export async function scheduleWaterReminder(intervalHours: number) {
// Cancel existing notifications
await Notifications.cancelAllScheduledNotificationsAsync();
// Schedule new reminder
await Notifications.scheduleNotificationAsync({
content: {
title: 'Time to hydrate 💧',
body: 'Drink a glass of water to stay healthy',
sound: 'default',
},
trigger: {
type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL,
seconds: intervalHours * 3600,
repeats: true,
},
});
}For a deeper dive into push notification patterns, How to Implement Push Notifications in Rork Apps provides a thorough walkthrough of the entire notification lifecycle.
Step 5: Weekly Chart Display
The history screen shows the past 7 days as a bar chart. Visualizing data over time is a powerful motivator — users can see their consistency (or lack thereof) at a glance.
Implement the history screen as follows:
- Bar chart showing past 7 days of water intake
- Use react-native-chart-kit or victory-native
- Display intake (ml) labels on each bar
- Show goal line as a dashed line
- Bars turn green on days the goal was met
- Show weekly average and achievement rate at the top// screens/HistoryScreen.tsx — expected output (excerpt)
import { BarChart } from 'react-native-chart-kit';
import { Dimensions } from 'react-native';
const screenWidth = Dimensions.get('window').width;
// Format past 7 days of data
const chartData = {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [{
data: weeklyData.map(d => d.totalAmount),
colors: weeklyData.map(d =>
// Green if goal met, blue otherwise
(opacity = 1) => d.totalAmount >= dailyGoal
? `rgba(34, 197, 94, ${opacity})`
: `rgba(59, 130, 246, ${opacity})`
),
}],
};
return (
<BarChart
data={chartData}
width={screenWidth - 32}
height={220}
yAxisSuffix="ml"
chartConfig={{
backgroundColor: '#ffffff',
backgroundGradientFrom: '#ffffff',
backgroundGradientTo: '#f0f9ff',
decimalPlaces: 0,
color: (opacity = 1) => `rgba(59, 130, 246, ${opacity})`,
}}
fromZero
showValuesOnTopOfBars
/>
);If you want to explore chart customization further, Building an Interactive Chart Dashboard with Rork and Victory Native covers advanced visualization techniques in detail.
Step 6: Polishing the UX
Once the core functionality works, it's time to add the finishing touches that make the app feel delightful to use:
Make these UX improvements:
1. Add haptic feedback to quick-add buttons (expo-haptics)
2. Splash animation when water is added (Lottie)
3. Confetti effect when daily goal is reached
4. Dark mode support
5. Custom amount input modal (for quantities other than 150/250/500ml)Haptic feedback is a small detail, but it gives users a satisfying sense of confirmation when they log their intake. In health and wellness apps, these tactile responses have been shown to improve long-term engagement and retention.
Summary
In this tutorial, you've built a complete water intake tracker app using Rork — from project setup to data persistence, circular progress visualization, scheduled reminders, weekly analytics charts, and UX polish.
This app is an excellent starting point in the healthcare app category. From here, you can expand it with food logging, exercise tracking, social goal-sharing with friends, or even integration with wearable devices to create a full-featured wellness app.
With Rork, natural language prompts are all it takes to bring an app like this to life. The best way to improve at app development is to start building — so go ahead and give it a try.